elitak / nixos-infect

[GPLv3+] install nixos over the existing OS in a DigitalOcean droplet (and others with minor modifications)
GNU General Public License v3.0
1.3k stars 214 forks source link

fix: Authorized keys parsing and extraction #187

Closed thegleich closed 5 months ago

thegleich commented 8 months ago

Close https://github.com/elitak/nixos-infect/issues/160

Fix incorrect handling of sk-variant keys when reading authorized keys Fix a security issue with the commented out ssh key

According to specification there are two additional variants that need to be handled:

sk-ecdsa-sha2-nistp256@openssh.com
sk-ssh-ed25519@openssh.com

Sed regular expressions are quite limited, and it wasn't possible to force the first group to match the longest expression. The way this was handled was by observing that either: 1) a line starts with an option list (as per specification) and has a space delimited sk-, ecdsa- or ssh prefix 2) a line starts with an above-mentioned prefix 3) a line starts with a comment

Option 1) is the only one that we need to replace and extract, others should be copied as is.

While exploring this, I've discovered a security issue with nixos-infect removing a comment and allowing a commented out key to be used.

I wasn't sure where the tests should land so I'll document my testing procedure here.

echo '
sk-ssh-ed25519@openssh.com A1...B1 comment1
sk-ecdsa-sha2-nistp256@openssh.com B2..C2 comment2
ecdsa-sha2-nistp256 B3..C3 comment3
ecdsa-sha2-nistp384 B4..C4 comment4
ecdsa-sha2-nistp521 B5..C5 comment5
no-port-forwarding,no-agent-forwarding, sk-ssh-ed25519@openssh.com B6..C6 comment6
# ssh-ed25519 B7..C7 comment7
ssh-dss B8..C8 comment8
ssh-rsa B9..C9 comment9

no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"ubuntu\" rather than the user \"root\".';echo;sleep 10" ssh-ed25519 AAAAdeadbeefxxxxxxxxxx.......' > test_case

I've included the test-case from https://github.com/elitak/nixos-infect/issues/43.

old_regex=$(sed -E 's/^.*((ssh|ecdsa)-[^[:space:]]+)[[:space:]]+([^[:space:]]+)([[:space:]]*.*)$/\1 \3\4/' test_case)
new_regex=$(sed -E 's/^[^#].*[[:space:]]((sk-ssh|sk-ecdsa|ssh|ecdsa)-[^[:space:]]+)[[:space:]]+([^[:space:]]+)([[:space:]]*.*)$/\1 \3\4/' test_case)
vimdiff test_case <(echo -e "${old_regex}") <(echo -e "${new_regex}")
Screenshot 2023-12-08 at 07 18 37