forked from containers/podman
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The e2e test introduced by this PR verifies that the command `system connection add` against an SSH server parses and updates correctly the local `known_hosts` file. Depends on containers/common#2212 Fixes containers#23575 Signed-off-by: Mario Loriedo <[email protected]>
- Loading branch information
Showing
11 changed files
with
1,073 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
package integration | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"net" | ||
|
@@ -437,16 +438,6 @@ qe ssh://[email protected]:2222/run/podman/podman.sock ~/.ssh/id_rsa false true | |
u, err := user.Current() | ||
Expect(err).ShouldNot(HaveOccurred()) | ||
|
||
// Ensure that the remote end uses our built podman | ||
if os.Getenv("PODMAN_BINARY") == "" { | ||
err = os.Setenv("PODMAN_BINARY", podmanTest.PodmanBinary) | ||
Expect(err).ShouldNot(HaveOccurred()) | ||
|
||
defer func() { | ||
os.Unsetenv("PODMAN_BINARY") | ||
}() | ||
} | ||
|
||
cmd := exec.Command(podmanTest.RemotePodmanBinary, | ||
"system", "connection", "add", | ||
"--default", | ||
|
@@ -488,5 +479,134 @@ qe ssh://[email protected]:2222/run/podman/podman.sock ~/.ssh/id_rsa false true | |
Expect(lsSession).Should(Exit(0)) | ||
Expect(string(lsSession.Out.Contents())).To(Equal("QA " + uri.String() + " " + filepath.Join(u.HomeDir, ".ssh", "id_ed25519") + " true true\n")) | ||
}) | ||
|
||
It("add ssh:// with known_hosts file", func() { | ||
u, err := user.Current() | ||
Expect(err).ShouldNot(HaveOccurred()) | ||
|
||
currentSSHServerHostname := "localhost" | ||
currentSSHServerFakeKey := currentSSHServerHostname + " ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGnBlHlwqleAtyzT01mLa+DXQFyxX8T0oa8odcEZ2/07" | ||
differentSSHServerKey := "differentserver ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGnBlHlwqleAtyzT01mLa+DXQFyxX8T0oa8odcEZ2/07" | ||
|
||
// Retrieve current SSH server first two keys | ||
// with `ssh-keyscan localhost` | ||
cmd := exec.Command("ssh-keyscan", currentSSHServerHostname) | ||
session, err := Start(cmd, GinkgoWriter, GinkgoWriter) | ||
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("ssh-keyscan %s failed to execute", currentSSHServerHostname)) | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(0)) | ||
Expect(session.Out.Contents()).ShouldNot(BeEmpty()) | ||
// Even if no error occurs, ssh-keyscan writes the | ||
// list of hosts to stderr | ||
Expect(session.Err.Contents()).ShouldNot(BeEmpty()) | ||
serverKeys := bytes.Split(session.Out.Contents(), []byte("\n")) | ||
Expect(len(serverKeys)).Should(BeNumerically(">=", 2), fmt.Sprintf("ssh-keyscan %s returned less then 2 keys", currentSSHServerHostname)) | ||
currentSSHServerFirstKey := string(serverKeys[0]) | ||
currentSSHServerSecondKey := string(serverKeys[1]) | ||
|
||
khTests := [] struct { | ||
description string | ||
initialKhKeys []string | ||
shouldFail bool | ||
shouldAddKey bool | ||
} { | ||
{ | ||
"known_host with a public key of the SSH server that matches the SSH server first key", | ||
[]string{currentSSHServerFirstKey}, | ||
false, | ||
false, | ||
}, | ||
{ | ||
"known_host with a public key of the SSH server that matches SSH server second key", | ||
[]string{currentSSHServerSecondKey}, | ||
false, | ||
false, | ||
}, | ||
{ | ||
"known_host with a fake public key of the SSH server that doesn't match any of the SSH server keys (should fail)", | ||
[]string{currentSSHServerFakeKey}, | ||
true, | ||
false, | ||
}, | ||
{ | ||
"known_host with no public key for the SSH server (new key should be added)", | ||
[]string{differentSSHServerKey}, | ||
false, | ||
true, | ||
}, | ||
{ | ||
"known_host not existing (should be created and a new key should be added)", | ||
[]string{}, | ||
false, | ||
true, | ||
}, | ||
} | ||
|
||
for _, khTest := range khTests { | ||
GinkgoWriter.Printf("Testing with: %s\n", khTest.description) | ||
|
||
// To use a different known_hosts file than the one | ||
// in the user's home directory we generate a new one | ||
// and change HOME environment variable to point to it. | ||
|
||
// Create a temporary directory | ||
tempHome, err := os.MkdirTemp("", "known_hosts-*") | ||
Expect(err).ToNot(HaveOccurred()) | ||
defer os.RemoveAll(tempHome) | ||
|
||
// Create an .ssh directory in the temporary directory | ||
tempSSHDir := filepath.Join(tempHome, ".ssh") | ||
err = os.Mkdir(tempSSHDir, 0700) | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
||
// Create known_hosts file if needed | ||
khFilePath := filepath.Join(tempSSHDir, "known_hosts") | ||
if len(khTest.initialKhKeys) > 0 { | ||
khFile, err := os.Create(khFilePath) | ||
Expect(err).ToNot(HaveOccurred()) | ||
defer khFile.Close() | ||
err = os.WriteFile(khFilePath, []byte(strings.Join(khTest.initialKhKeys, "\n")), 0600) | ||
Expect(err).ToNot(HaveOccurred()) | ||
} | ||
|
||
// Set HOME to the temporary directory | ||
err = os.Setenv("HOME", tempHome) | ||
Expect(err).ToNot(HaveOccurred()) | ||
defer os.Setenv("HOME", u.HomeDir) | ||
|
||
// Run podman system connection add | ||
cmd := exec.Command(podmanTest.RemotePodmanBinary, | ||
"system", "connection", "add", | ||
"--default", | ||
"--identity", filepath.Join(u.HomeDir, ".ssh", "id_ed25519"), | ||
"QA", | ||
fmt.Sprintf("ssh://%s@%s", u.Username, currentSSHServerHostname)) | ||
session, err := Start(cmd, GinkgoWriter, GinkgoWriter) | ||
Expect(err).ToNot(HaveOccurred(), fmt.Sprintf("%q failed to execute", podmanTest.RemotePodmanBinary)) | ||
Expect(session.Out.Contents()).Should(BeEmpty()) | ||
|
||
if khTest.shouldFail { | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(125)) | ||
Expect(session.Err.Contents()).ShouldNot(BeEmpty()) | ||
} else { | ||
Eventually(session, DefaultWaitTimeout).Should(Exit(0)) | ||
Expect(session.Err.Contents()).Should(BeEmpty()) | ||
} | ||
|
||
// If the known_hosts file didn't exist, it should | ||
// have been created | ||
if len(khTest.initialKhKeys) == 0 { | ||
Expect(khFilePath).To(BeAnExistingFile()) | ||
} | ||
|
||
// If the known_hosts file didn't contain the SSH server | ||
// public key it should have been added | ||
if khTest.shouldAddKey { | ||
khFileContent, err := os.ReadFile(khFilePath) | ||
Expect(err).ToNot(HaveOccurred()) | ||
khLines := bytes.Split(khFileContent, []byte("\n")) | ||
Expect(len(khLines)).To(BeNumerically(">", len(khTest.initialKhKeys))) | ||
} | ||
} | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.