Turn IdentitiesOnly off for ssh to (closes #74) #85
@@ -219,11 +219,15 @@ first, or pass `-o StrictHostKeyChecking=accept-new` after `--`.
|
|||||||
|
|
||||||
Derives the key, serves it from an SSH agent that runs inside the tool on a unix
|
Derives the key, serves it from an SSH agent that runs inside the tool on a unix
|
||||||
socket in a new private `0700` temporary directory, then runs the system `ssh`
|
socket in a new private `0700` temporary directory, then runs the system `ssh`
|
||||||
with `-o IdentityAgent=<that socket>` followed by the host and all remaining
|
with `-o IdentityAgent=<that socket> -o IdentitiesOnly=no` followed by the host
|
||||||
arguments unchanged. The tool exits with `ssh`'s exit status and removes the
|
and all remaining arguments unchanged. Without `IdentitiesOnly=no`, an
|
||||||
socket and directory on the way out. The private key is never written to disk. A
|
`IdentitiesOnly yes` in the user's `ssh` configuration keeps the derived key
|
||||||
SIGINT, SIGTERM or SIGHUP ends `ssh` and still removes the socket and directory,
|
from being offered. The agent holds no other key, so turning it off adds nothing
|
||||||
and the tool then exits with status 1 unless `ssh` reported one of its own.
|
else to what `ssh` offers. The tool exits with `ssh`'s exit status and removes
|
||||||
|
the socket and directory on the way out. The private key is never written to
|
||||||
|
disk. A SIGINT, SIGTERM or SIGHUP ends `ssh` and still removes the socket and
|
||||||
|
directory, and the tool then exits with status 1 unless `ssh` reported one of
|
||||||
|
its own.
|
||||||
|
|
||||||
## age identities: `keyfunc age`
|
## age identities: `keyfunc age`
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,13 @@ func to() *cobra.Command {
|
|||||||
|
|
||||||
defer served.Stop()
|
defer served.Stop()
|
||||||
|
|
||||||
|
// IdentitiesOnly yes in the user's ssh configuration
|
||||||
|
// would keep the agent's key from being offered. The
|
||||||
|
// agent holds only the derived key, so turning it off
|
||||||
|
// adds no other key.
|
||||||
argv := slices.Concat([]string{
|
argv := slices.Concat([]string{
|
||||||
"-o", "IdentityAgent=" + served.Socket(),
|
"-o", "IdentityAgent=" + served.Socket(),
|
||||||
|
"-o", "IdentitiesOnly=no",
|
||||||
}, args)
|
}, args)
|
||||||
|
|
||||||
return connect(ctx, argv)
|
return connect(ctx, argv)
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ func TestSSHIsPointedAtTheAgentAndItsStatusIsHandedOn(t *testing.T) {
|
|||||||
|
|
||||||
given := recorded(t, arguments)
|
given := recorded(t, arguments)
|
||||||
require.Equal(t, "-o", given[0])
|
require.Equal(t, "-o", given[0])
|
||||||
require.Equal(t, []string{host, remoteCommand}, given[2:])
|
require.Equal(t, []string{host, remoteCommand}, given[4:])
|
||||||
|
|
||||||
// The stand-in wrote the path down only because there really was
|
// The stand-in wrote the path down only because there really was
|
||||||
// a socket there while it ran.
|
// a socket there while it ran.
|
||||||
@@ -596,6 +596,26 @@ func TestSSHIsPointedAtTheAgentAndItsStatusIsHandedOn(t *testing.T) {
|
|||||||
require.NoDirExists(t, filepath.Dir(socket))
|
require.NoDirExists(t, filepath.Dir(socket))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIdentitiesOnlyIsTurnedOffBeforeTheHost(t *testing.T) {
|
||||||
|
t.Setenv(mnemonic.Variable, example())
|
||||||
|
|
||||||
|
arguments, _ := pretendCall(t)
|
||||||
|
|
||||||
|
_, err := execute(t, subcommand, "to", host, remoteCommand)
|
||||||
|
|
||||||
|
var passed ssh.StatusError
|
||||||
|
|
||||||
|
require.ErrorAs(t, err, &passed)
|
||||||
|
|
||||||
|
// IdentitiesOnly yes in the user's ssh configuration keeps ssh
|
||||||
|
// from offering the agent's key. An option given before the host
|
||||||
|
// wins over the configuration.
|
||||||
|
given := recorded(t, arguments)
|
||||||
|
require.Equal(t,
|
||||||
|
[]string{"-o", "IdentitiesOnly=no", host, remoteCommand}, given[2:],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTheToolEndsWithTheStatusSSHEndedWith(t *testing.T) {
|
func TestTheToolEndsWithTheStatusSSHEndedWith(t *testing.T) {
|
||||||
t.Setenv(mnemonic.Variable, example())
|
t.Setenv(mnemonic.Variable, example())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user