···99 default = false;
1010 description =
1111 '' When enabled, GNU software is chosen by default whenever a there is
1212- a choice between GNU and non-GNU software.
1212+ a choice between GNU and non-GNU software (e.g., GNU lsh
1313+ vs. OpenSSH).
1314 '';
1415 };
1516 };
···3132 # GNU GRUB, where available.
3233 boot.loader.grub.enable = !pkgs.stdenv.isArm;
3334 boot.loader.grub.version = 2;
3535+3636+ # GNU lsh.
3737+ services.openssh.enable = false;
3838+ services.lshd.enable = true;
3939+ programs.ssh.startAgent = false;
4040+ services.xserver.startGnuPGAgent = true;
34413542 # TODO: GNU dico.
3643 # TODO: GNU Inetutils' inetd.
+176
nixos/modules/services/networking/ssh/lshd.nix
···11+{ config, lib, pkgs, ... }:
22+33+with lib;
44+55+let
66+77+ inherit (pkgs) lsh;
88+99+ cfg = config.services.lshd;
1010+1111+in
1212+1313+{
1414+1515+ ###### interface
1616+1717+ options = {
1818+1919+ services.lshd = {
2020+2121+ enable = mkOption {
2222+ default = false;
2323+ description = ''
2424+ Whether to enable the GNU lshd SSH2 daemon, which allows
2525+ secure remote login.
2626+ '';
2727+ };
2828+2929+ portNumber = mkOption {
3030+ default = 22;
3131+ description = ''
3232+ The port on which to listen for connections.
3333+ '';
3434+ };
3535+3636+ interfaces = mkOption {
3737+ default = [];
3838+ description = ''
3939+ List of network interfaces where listening for connections.
4040+ When providing the empty list, `[]', lshd listens on all
4141+ network interfaces.
4242+ '';
4343+ example = [ "localhost" "1.2.3.4:443" ];
4444+ };
4545+4646+ hostKey = mkOption {
4747+ default = "/etc/lsh/host-key";
4848+ description = ''
4949+ Path to the server's private key. Note that this key must
5050+ have been created, e.g., using "lsh-keygen --server |
5151+ lsh-writekey --server", so that you can run lshd.
5252+ '';
5353+ };
5454+5555+ syslog = mkOption {
5656+ default = true;
5757+ description = ''Whether to enable syslog output.'';
5858+ };
5959+6060+ passwordAuthentication = mkOption {
6161+ default = true;
6262+ description = ''Whether to enable password authentication.'';
6363+ };
6464+6565+ publicKeyAuthentication = mkOption {
6666+ default = true;
6767+ description = ''Whether to enable public key authentication.'';
6868+ };
6969+7070+ rootLogin = mkOption {
7171+ default = false;
7272+ description = ''Whether to enable remote root login.'';
7373+ };
7474+7575+ loginShell = mkOption {
7676+ default = null;
7777+ description = ''
7878+ If non-null, override the default login shell with the
7979+ specified value.
8080+ '';
8181+ example = "/nix/store/xyz-bash-10.0/bin/bash10";
8282+ };
8383+8484+ srpKeyExchange = mkOption {
8585+ default = false;
8686+ description = ''
8787+ Whether to enable SRP key exchange and user authentication.
8888+ '';
8989+ };
9090+9191+ tcpForwarding = mkOption {
9292+ default = true;
9393+ description = ''Whether to enable TCP/IP forwarding.'';
9494+ };
9595+9696+ x11Forwarding = mkOption {
9797+ default = true;
9898+ description = ''Whether to enable X11 forwarding.'';
9999+ };
100100+101101+ subsystems = mkOption {
102102+ description = ''
103103+ List of subsystem-path pairs, where the head of the pair
104104+ denotes the subsystem name, and the tail denotes the path to
105105+ an executable implementing it.
106106+ '';
107107+ };
108108+109109+ };
110110+111111+ };
112112+113113+114114+ ###### implementation
115115+116116+ config = mkIf cfg.enable {
117117+118118+ services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ];
119119+120120+ systemd.services.lshd = {
121121+ description = "GNU lshd SSH2 daemon";
122122+123123+ after = [ "network-interfaces.target" ];
124124+125125+ wantedBy = [ "multi-user.target" ];
126126+127127+ environment = {
128128+ LD_LIBRARY_PATH = config.system.nssModules.path;
129129+ };
130130+131131+ preStart = ''
132132+ test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
133133+ test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
134134+135135+ if ! test -f /var/spool/lsh/yarrow-seed-file
136136+ then
137137+ # XXX: It would be nice to provide feedback to the
138138+ # user when this fails, so that they can retry it
139139+ # manually.
140140+ ${lsh}/bin/lsh-make-seed --sloppy \
141141+ -o /var/spool/lsh/yarrow-seed-file
142142+ fi
143143+144144+ if ! test -f "${cfg.hostKey}"
145145+ then
146146+ ${lsh}/bin/lsh-keygen --server | \
147147+ ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
148148+ fi
149149+ '';
150150+151151+ script = with cfg; ''
152152+ ${lsh}/sbin/lshd --daemonic \
153153+ --password-helper="${lsh}/sbin/lsh-pam-checkpw" \
154154+ -p ${toString portNumber} \
155155+ ${if interfaces == [] then ""
156156+ else (concatStrings (map (i: "--interface=\"${i}\"")
157157+ interfaces))} \
158158+ -h "${hostKey}" \
159159+ ${if !syslog then "--no-syslog" else ""} \
160160+ ${if passwordAuthentication then "--password" else "--no-password" } \
161161+ ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
162162+ ${if rootLogin then "--root-login" else "--no-root-login" } \
163163+ ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \
164164+ ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
165165+ ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
166166+ ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
167167+ --subsystems=${concatStringsSep ","
168168+ (map (pair: (head pair) + "=" +
169169+ (head (tail pair)))
170170+ subsystems)}
171171+ '';
172172+ };
173173+174174+ security.pam.services.lshd = {};
175175+ };
176176+}
+49
pkgs/tools/networking/lsh/default.nix
···11+{ stdenv, fetchurl, gperf, guile, gmp, zlib, liboop, readline, gnum4, pam
22+, nettools, lsof, procps }:
33+44+stdenv.mkDerivation rec {
55+ name = "lsh-2.0.4";
66+ src = fetchurl {
77+ url = "mirror://gnu/lsh/${name}.tar.gz";
88+ sha256 = "614b9d63e13ad3e162c82b6405d1f67713fc622a8bc11337e72949d613713091";
99+ };
1010+1111+ patches = [ ./pam-service-name.patch ./lshd-no-root-login.patch ];
1212+1313+ preConfigure = ''
1414+ # Patch `lsh-make-seed' so that it can gather enough entropy.
1515+ sed -i "src/lsh-make-seed.c" \
1616+ -e "s|/usr/sbin/arp|${nettools}/sbin/arp|g ;
1717+ s|/usr/bin/netstat|${nettools}/bin/netstat|g ;
1818+ s|/usr/local/bin/lsof|${lsof}/bin/lsof|g ;
1919+ s|/bin/vmstat|${procps}/bin/vmstat|g ;
2020+ s|/bin/ps|${procps}/bin/sp|g ;
2121+ s|/usr/bin/w|${procps}/bin/w|g ;
2222+ s|/usr/bin/df|$(type -P df)|g ;
2323+ s|/usr/bin/ipcs|$(type -P ipcs)|g ;
2424+ s|/usr/bin/uptime|$(type -P uptime)|g"
2525+2626+ # Skip the `configure' script that checks whether /dev/ptmx & co. work as
2727+ # expected, because it relies on impurities (for instance, /dev/pts may
2828+ # be unavailable in chroots.)
2929+ export lsh_cv_sys_unix98_ptys=yes
3030+ '';
3131+3232+ buildInputs = [ gperf guile gmp zlib liboop readline gnum4 pam ];
3333+3434+ meta = {
3535+ description = "GPL'd implementation of the SSH protocol";
3636+3737+ longDescription = ''
3838+ lsh is a free implementation (in the GNU sense) of the ssh
3939+ version 2 protocol, currently being standardised by the IETF
4040+ SECSH working group.
4141+ '';
4242+4343+ homepage = http://www.lysator.liu.se/~nisse/lsh/;
4444+ license = stdenv.lib.licenses.gpl2Plus;
4545+4646+ maintainers = [ ];
4747+ platforms = [ "x86_64-linux" ];
4848+ };
4949+}