README child-mnemonic vector and host-key note; ssh install refuses a ~/.ssh it cannot enter (closes #51)
check / check (push) Successful in 2m45s

The README gains the child mnemonic that `keyfunc mnemonic` prints for
the abandon ... about mnemonic at index 0, asserted by the README
vectors test, and says that `ssh install` needs the host key already
known, with the two ways round it.

`ssh install` now also lists `.ssh/.` before fetching. A `.ssh` that can
be read but not entered lists as empty, so the fetch read it as holding
no file and tried an upload that could only fail. The listing of
`.ssh/.` fails instead, and the tool refuses before any upload, saying
the directory cannot be entered. The test that failed the put with a
file where `.ssh` belongs now uses a `.ssh` of mode 500.

Model: opus-5-5
This commit is contained in:
2026-10-04 04:58:52 +00:00
parent 1ddc2c747a
commit 82e35190c8
5 changed files with 142 additions and 63 deletions
+12 -4
View File
@@ -80,8 +80,11 @@ 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.
// directory it cannot find is reported one way, and one it cannot read
// another, and only the first is read as a host with no .ssh yet. A
// .ssh that can be read but not entered lists as empty, and the
// listing of .ssh/. that follows reports that path, not .ssh, as not
// found.
func TestTheDirectoryIsReadAsAbsentOnlyFromTheListingSayingSo(t *testing.T) {
t.Parallel()
@@ -102,11 +105,16 @@ func TestTheDirectoryIsReadAsAbsentOnlyFromTheListingSayingSo(t *testing.T) {
`Can't ls: "/home/someone/.ssh" not found` + "\n",
want: true,
},
"the directory is there and cannot be entered": {
"the directory is there and cannot be read": {
said: listed +
`remote readdir("/home/someone/.ssh/"): Permission denied` + "\n",
want: false,
},
"the directory is there and cannot be entered": {
said: listed + "sftp> ls -1 .ssh/.\n" +
`Can't ls: "/home/someone/.ssh/." not found` + "\n",
want: false,
},
"some other directory is not there": {
said: listed + `Can't ls: "/home/someone/.config" not found` + "\n",
want: false,
@@ -122,7 +130,7 @@ func TestTheDirectoryIsReadAsAbsentOnlyFromTheListingSayingSo(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()
if directoryAbsent(listing.said) != listing.want {
if listingNotFound(listing.said, directory) != listing.want {
t.Errorf(
"read as absent: %t, wanted %t, from:\n%s",
!listing.want, listing.want, listing.said,