ssh install tells a missing .ssh from one it cannot enter (closes #10)
check / check (push) Failing after 0s
check / check (push) Failing after 0s
The first sftp session now lists .ssh before fetching authorized_keys. The file reads as empty only when sftp reports .ssh itself as missing, or the listing succeeded and the file is reported missing. A directory or file that is there but cannot be read fails the run and nothing is written, so no existing authorized_keys is replaced by content that was not built from what was read. An .ssh that already exists keeps its mode; the directory is made and set to 0700 only when none was found. The README describes the rule and states batch mode's limit: a key or an agent must authenticate. Model: opus-4-8 (implementation); fable-5-1 (summary)
This commit was merged in pull request #27.
This commit is contained in:
@@ -10,6 +10,7 @@ import "testing"
|
||||
const (
|
||||
echoed = `sftp> get .ssh/authorized_keys "/tmp/keyfunc/authorized_keys"
|
||||
`
|
||||
listed = "sftp> ls -1 .ssh\n"
|
||||
warning = `Warning: Identity file /gone not accessible: ` +
|
||||
"No such file or directory.\n"
|
||||
)
|
||||
@@ -76,3 +77,57 @@ func TestAbsenceIsReadOnlyFromWhatSFTPSaidAboutAuthorizedKeys(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestTheDirectoryIsReadAsAbsentOnlyFromTheListingSayingSo holds the
|
||||
// wordings the OpenSSH client was seen to use when a listing fails: a
|
||||
// directory it cannot find is reported one way, and one it cannot enter
|
||||
// another, and only the first is read as a host with no .ssh yet.
|
||||
func TestTheDirectoryIsReadAsAbsentOnlyFromTheListingSayingSo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
listings := map[string]struct {
|
||||
said string
|
||||
want bool
|
||||
}{
|
||||
"the directory is not there": {
|
||||
said: listed + `Can't ls: "/home/someone/.ssh" not found` + "\n",
|
||||
want: true,
|
||||
},
|
||||
"the directory is not there, named as it was asked for": {
|
||||
said: listed + `Can't ls: ".ssh" not found` + "\n",
|
||||
want: true,
|
||||
},
|
||||
"the directory is not there and an identity file is not either": {
|
||||
said: warning + listed +
|
||||
`Can't ls: "/home/someone/.ssh" not found` + "\n",
|
||||
want: true,
|
||||
},
|
||||
"the directory is there and cannot be entered": {
|
||||
said: listed +
|
||||
`remote readdir("/home/someone/.ssh/"): Permission denied` + "\n",
|
||||
want: false,
|
||||
},
|
||||
"some other directory is not there": {
|
||||
said: listed + `Can't ls: "/home/someone/.config" not found` + "\n",
|
||||
want: false,
|
||||
},
|
||||
"the connection did not come up": {
|
||||
said: "ssh: connect to host example.com port 22: " +
|
||||
"Connection refused\nConnection closed\n",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for name, listing := range listings {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if directoryAbsent(listing.said) != listing.want {
|
||||
t.Errorf(
|
||||
"read as absent: %t, wanted %t, from:\n%s",
|
||||
!listing.want, listing.want, listing.said,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user