The ssh install command works over sftp (closes #10)
All checks were successful
check / check (push) Successful in 20s

The command no longer sends a shell script to the host. It fetches
~/.ssh/authorized_keys with the system sftp in batch mode, adds the key
line here, and writes the file back in a second session: mkdir and chmod
on ~/.ssh, put to authorized_keys.keyfunc-<random>, chmod 600, then
rename over authorized_keys. A run that adds a line connects twice; one
that finds the line there connects once and stops. A failed step leaves
everything as it is and names the uploaded file.

sftp echoes the commands it runs, so all of its output goes to standard
error and the tool prints only "added" or "already present". Batch mode
cannot prompt for a password; the README says so.

Model: opus-5
This commit is contained in:
2026-09-08 04:14:46 +00:00
parent a2a0890ded
commit cac775c100
3 changed files with 325 additions and 108 deletions

View File

@@ -88,17 +88,37 @@ Prints the unencrypted private key in OpenSSH format (the
and nothing else, so it can be redirected into a file. The key's comment is the
same as for `pub`.
### `keyfunc ssh install <[user@]host> [-- ssh options...]`
### `keyfunc ssh install <[user@]host> [-- sftp options...]`
Runs the system `ssh` to the host and, on the host:
Adds the `pub` line to `~/.ssh/authorized_keys` on the host. No command is run
on the host: the file is fetched, changed here, and written back with the
system `sftp` client in batch mode.
- creates `~/.ssh` with mode `0700` if it is missing;
- creates `~/.ssh/authorized_keys` with mode `0600` if it is missing;
- appends the `pub` line only if an identical line is not already there.
The first connection fetches `~/.ssh/authorized_keys`; a host that has no such
file yet reads as empty. If an identical line is already in the file, the tool
prints `already present` and connects no further. Otherwise the line is added
(after a newline, if the file did not end with one) and a second connection:
It then prints `added` or `already present`. How this `ssh` connection
authenticates is up to the user's normal `ssh` setup (existing keys, agent,
password). Anything after `--` is passed to `ssh` unchanged.
- creates `~/.ssh` and sets it to mode `0700`;
- uploads the new file as `~/.ssh/authorized_keys.keyfunc-<random>` and sets it
to mode `0600`;
- renames that file over `~/.ssh/authorized_keys`.
The tool then prints `added`. So a run that adds a line connects twice. The
rename is the step that either happens or does not: the file on the host is
never half-written. `sftp` does it in one step against servers that offer
OpenSSH's POSIX rename extension, as OpenSSH's own server does; a server
without it may refuse to rename onto a file that is already there.
If a step fails, the tool prints what `sftp` said, names the uploaded file if
there was one, removes nothing, and exits with status 1. Everything `sftp`
writes goes to standard error, so the tool's own standard output is only
`added` or `already present`.
Anything after `--` is passed to `sftp` unchanged, which is where the port goes
(`-P 2222`, not `-p`). How the connection authenticates is up to the user's
normal `ssh` setup, except that batch mode does not prompt: a key or an agent
has to do it, not a typed password.
### `keyfunc ssh to <host> [ssh arguments...]`