at 18.03-beta 4.4 kB view raw
1import ./make-test.nix ({ pkgs, latestKernel ? false, ... }: 2 3let 4 oathSnakeoilSecret = "cdd4083ef8ff1fa9178c6d46bfb1a3"; 5 6 # With HOTP mode the password is calculated based on a counter of 7 # how many passwords have been made. In this env, we'll always be on 8 # the 0th counter, so the password is static. 9 # 10 # Generated in nix-shell -p oathToolkit 11 # via: oathtool -v -d6 -w10 cdd4083ef8ff1fa9178c6d46bfb1a3 12 # and picking a the first 4: 13 oathSnakeOilPassword1 = "143349"; 14 oathSnakeOilPassword2 = "801753"; 15 oathSnakeOilPassword3 = "019933"; 16 oathSnakeOilPassword4 = "403895"; 17 18 alicePassword = "foobar"; 19 # Generated via: mkpasswd -m sha-512 and passing in "foobar" 20 hashedAlicePassword = "$6$MsMrE1q.1HrCgTS$Vq2e/uILzYjSN836TobAyN9xh9oi7EmCmucnZID25qgPoibkw8qTCugiAPnn4eCGvn1A.7oEBFJaaGUaJsQQY."; 21 22in 23{ 24 name = "pam-oath-login"; 25 26 machine = 27 { config, pkgs, lib, ... }: 28 { 29 security.pam.oath = { 30 enable = true; 31 }; 32 33 users.extraUsers.alice = { 34 isNormalUser = true; 35 name = "alice"; 36 uid = 1000; 37 hashedPassword = hashedAlicePassword; 38 extraGroups = [ "wheel" ]; 39 createHome = true; 40 home = "/home/alice"; 41 }; 42 43 44 systemd.services.setupOathSnakeoilFile = { 45 wantedBy = [ "default.target" ]; 46 before = [ "default.target" ]; 47 unitConfig = { 48 type = "oneshot"; 49 RemainAfterExit = true; 50 }; 51 script = '' 52 touch /etc/users.oath 53 chmod 600 /etc/users.oath 54 chown root /etc/users.oath 55 echo "HOTP/E/6 alice - ${oathSnakeoilSecret}" > /etc/users.oath 56 ''; 57 }; 58 }; 59 60 testScript = 61 '' 62 $machine->waitForUnit('multi-user.target'); 63 $machine->waitUntilSucceeds("pgrep -f 'agetty.*tty1'"); 64 $machine->screenshot("postboot"); 65 66 67 subtest "Invalid password", sub { 68 $machine->fail("pgrep -f 'agetty.*tty2'"); 69 $machine->sendKeys("alt-f2"); 70 $machine->waitUntilSucceeds("[ \$(fgconsole) = 2 ]"); 71 $machine->waitForUnit('getty@tty2.service'); 72 $machine->waitUntilSucceeds("pgrep -f 'agetty.*tty2'"); 73 74 $machine->waitUntilTTYMatches(2, "login: "); 75 $machine->sendChars("alice\n"); 76 $machine->waitUntilTTYMatches(2, "login: alice"); 77 $machine->waitUntilSucceeds("pgrep login"); 78 79 $machine->waitUntilTTYMatches(2, "One-time password"); 80 $machine->sendChars("${oathSnakeOilPassword1}\n"); 81 $machine->waitUntilTTYMatches(2, "Password: "); 82 $machine->sendChars("blorg\n"); 83 $machine->waitUntilTTYMatches(2, "Login incorrect"); 84 }; 85 86 subtest "Invalid oath token", sub { 87 $machine->fail("pgrep -f 'agetty.*tty3'"); 88 $machine->sendKeys("alt-f3"); 89 $machine->waitUntilSucceeds("[ \$(fgconsole) = 3 ]"); 90 $machine->waitForUnit('getty@tty3.service'); 91 $machine->waitUntilSucceeds("pgrep -f 'agetty.*tty3'"); 92 93 $machine->waitUntilTTYMatches(3, "login: "); 94 $machine->sendChars("alice\n"); 95 $machine->waitUntilTTYMatches(3, "login: alice"); 96 $machine->waitUntilSucceeds("pgrep login"); 97 $machine->waitUntilTTYMatches(3, "One-time password"); 98 $machine->sendChars("000000\n"); 99 $machine->waitUntilTTYMatches(3, "Login incorrect"); 100 $machine->waitUntilTTYMatches(3, "login:"); 101 }; 102 103 subtest "Happy path (both passwords are mandatory to get us in)", sub { 104 $machine->fail("pgrep -f 'agetty.*tty4'"); 105 $machine->sendKeys("alt-f4"); 106 $machine->waitUntilSucceeds("[ \$(fgconsole) = 4 ]"); 107 $machine->waitForUnit('getty@tty4.service'); 108 $machine->waitUntilSucceeds("pgrep -f 'agetty.*tty4'"); 109 110 $machine->waitUntilTTYMatches(4, "login: "); 111 $machine->sendChars("alice\n"); 112 $machine->waitUntilTTYMatches(4, "login: alice"); 113 $machine->waitUntilSucceeds("pgrep login"); 114 $machine->waitUntilTTYMatches(4, "One-time password"); 115 $machine->sendChars("${oathSnakeOilPassword2}\n"); 116 $machine->waitUntilTTYMatches(4, "Password: "); 117 $machine->sendChars("${alicePassword}\n"); 118 119 $machine->waitUntilSucceeds("pgrep -u alice bash"); 120 $machine->sendChars("touch done4\n"); 121 $machine->waitForFile("/home/alice/done4"); 122 }; 123 124 ''; 125 126})