Skip to content

Commit

Permalink
Fix ssh keypath defaulting (#120)
Browse files Browse the repository at this point in the history
Signed-off-by: Kimmo Lehto <[email protected]>
  • Loading branch information
kke authored Sep 7, 2023
1 parent 15b7c99 commit 5e50bad
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
27 changes: 20 additions & 7 deletions ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"io"
"net"
"os"
"slices"
"sort"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -49,7 +51,7 @@ type PasswordCallback func() (secret string, err error)

var (
authMethodCache = sync.Map{}
defaultKeypaths = []string{"~/.ssh/id_rsa", "~/.ssh/identity", "~/.ssh/id_dsa"}
defaultKeypaths = []string{"~/.ssh/id_rsa", "~/.ssh/identity", "~/.ssh/id_dsa", "~/.ssh/id_ecdsa", "~/.ssh/id_ed25519"}
dummyhostKeyPaths []string
globalOnce sync.Once
knownHostsMU sync.Mutex
Expand Down Expand Up @@ -114,7 +116,15 @@ func expandAndValidatePath(path string) (string, error) {

func (c *SSH) keypathsFromConfig() []string {
log.Tracef("%s: trying to get a keyfile path from ssh config", c)
if idf := c.getConfigAll("IdentityFile"); len(idf) > 0 {
idf := c.getConfigAll("IdentityFile")
// https://github.com/kevinburke/ssh_config/blob/master/config.go#L254 says:
// TODO: IdentityFile has multiple default values that we should return
// To work around this, the hard coded list of known defaults are appended to the list
idf = append(idf, defaultKeypaths...)
sort.Strings(idf)
idf = slices.Compact(idf)

if len(idf) > 0 {
log.Tracef("%s: detected %d identity file paths from ssh config: %v", c, len(idf), idf)
return idf
}
Expand All @@ -125,11 +135,18 @@ func (c *SSH) keypathsFromConfig() []string {
func (c *SSH) initGlobalDefaults() {
log.Tracef("discovering global default keypaths")
dummyHostIdentityFiles := SSHConfigGetAll(hopefullyNonexistentHost, "IdentityFile")
// https://github.com/kevinburke/ssh_config/blob/master/config.go#L254 says:
// TODO: IdentityFile has multiple default values that we should return
// To work around this, the hard coded list of known defaults are appended to the list
dummyHostIdentityFiles = append(dummyHostIdentityFiles, defaultKeypaths...)
sort.Strings(dummyHostIdentityFiles)
dummyHostIdentityFiles = slices.Compact(dummyHostIdentityFiles)
for _, keyPath := range dummyHostIdentityFiles {
if expanded, err := expandAndValidatePath(keyPath); err != nil {
if expanded, err := expandAndValidatePath(keyPath); err == nil {
dummyhostKeyPaths = append(dummyhostKeyPaths, expanded)
}
}
log.Tracef("global default keypaths from ssh config: %+v", dummyhostKeyPaths)
}

func findUniq(a, b []string) (string, bool) {
Expand Down Expand Up @@ -163,10 +180,6 @@ func (c *SSH) SetDefaults() {
c.KeyPath = nil

paths := c.keypathsFromConfig()
if len(paths) == 0 {
// no paths found in ssh config either, use defaults
paths = append(paths, defaultKeypaths...)
}

for _, p := range paths {
expanded, err := expandAndValidatePath(p)
Expand Down
11 changes: 11 additions & 0 deletions test/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@ rig_test_key_from_path() {
RET=$exit_code
}

rig_test_key_from_default_location() {
color_echo "- Testing keypath from default location"
make create-host
mv .ssh/identity .ssh/id_ecdsa
set +e
HOME=$(pwd) ./rigtest -host 127.0.0.1:$(ssh_port node0) -user root
local exit_code=$?
set -e
RET=$exit_code
}

rig_test_protected_key_from_path() {
color_echo "- Testing regular keypath to encrypted key, two hosts"
make create-host KEY_PASSPHRASE=testPhrase REPLICAS=2
Expand Down

0 comments on commit 5e50bad

Please sign in to comment.