1{ pkgs, lib, ... }:
2
3let
4 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
5 xxh-shell-zsh = pkgs.stdenv.mkDerivation {
6 pname = "xxh-shell-zsh";
7 version = "";
8 src = pkgs.fetchFromGitHub {
9 owner = "xxh";
10 repo = "xxh-shell-zsh";
11 # gets rarely updated, we can then just replace the hash
12 rev = "91e1f84f8d6e0852c3235d4813f341230cac439f";
13 sha256 = "sha256-Y1FrIRxTd0yooK+ZzKcCd6bLSy5E2fRXYAzrIsm7rIc=";
14 };
15
16 postPatch = ''
17 substituteInPlace build.sh \
18 --replace "echo Install wget or curl" "cp ${zsh-portable-binary} zsh-5.8-linux-x86_64.tar.gz" \
19 --replace "command -v curl" "command -v this-should-not-trigger"
20 '';
21
22 installPhase = ''
23 mkdir -p $out
24 mv * $out/
25 '';
26 };
27
28 zsh-portable-binary = pkgs.fetchurl {
29 # kept in sync with https://github.com/xxh/xxh-shell-zsh/tree/master/build.sh#L27
30 url = "https://github.com/romkatv/zsh-bin/releases/download/v3.0.1/zsh-5.8-linux-x86_64.tar.gz";
31 sha256 = "sha256-i8flMd2Isc0uLoeYQNDnOGb/kK3oTFVqQgIx7aOAIIo=";
32 };
33in
34{
35 name = "xxh";
36 meta = with lib.maintainers; {
37 maintainers = [ lom ];
38 };
39
40 nodes = {
41 server =
42 { ... }:
43 {
44 services.openssh.enable = true;
45 users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
46 };
47
48 client =
49 { ... }:
50 {
51 programs.zsh.enable = true;
52 users.users.root.shell = pkgs.zsh;
53 environment.systemPackages = with pkgs; [
54 xxh
55 git
56 ];
57 };
58 };
59
60 testScript = ''
61 start_all()
62
63 client.succeed("mkdir -m 700 /root/.ssh")
64
65 client.succeed(
66 "cat ${snakeOilPrivateKey} > /root/.ssh/id_ecdsa"
67 )
68 client.succeed("chmod 600 /root/.ssh/id_ecdsa")
69
70 server.wait_for_unit("sshd")
71
72 client.succeed("xxh server -i /root/.ssh/id_ecdsa +hc \'echo $0\' +i +s zsh +I xxh-shell-zsh+path+${xxh-shell-zsh} | grep -Fq '/root/.xxh/.xxh/shells/xxh-shell-zsh/build/zsh-bin/bin/zsh'")
73 '';
74}