Skip to content

Commit

Permalink
Adds support for loading tctl creds from ~/.tsh profile
Browse files Browse the repository at this point in the history
This commit fixes #4439
  • Loading branch information
klizhentas authored and russjones committed Nov 10, 2020
1 parent 4d00e4a commit 9bdac2c
Show file tree
Hide file tree
Showing 6 changed files with 344 additions and 173 deletions.
2 changes: 1 addition & 1 deletion e
Submodule e updated from 441c6b to d0ea82
21 changes: 21 additions & 0 deletions lib/client/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,24 @@ func (k *Key) HostKeyCallback() (ssh.HostKeyCallback, error) {
return trace.AccessDenied("host %v is untrusted or Teleport CA has been rotated; try getting new credentials by logging in again ('tsh login') or re-exporting the identity file ('tctl auth sign' or 'tsh login -o'), depending on how you got them initially", host)
}, nil
}

// ProxyClientSSHConfig returns an ssh.ClientConfig with SSH credentials from this
// Key and HostKeyCallback matching SSH CAs in the Key.
//
// The config is set up to authenticate to proxy with the first
// available principal and trust local SSH CAs without asking
// for public keys.
//
func ProxyClientSSHConfig(k *Key, keyStore LocalKeyStore) (*ssh.ClientConfig, error) {
sshConfig, err := k.ClientSSHConfig()
if err != nil {
return nil, trace.Wrap(err)
}
principals, err := k.CertPrincipals()
if err != nil {
return nil, trace.Wrap(err)
}
sshConfig.User = principals[0]
sshConfig.HostKeyCallback = NewKeyStoreCertChecker(keyStore)
return sshConfig, nil
}
34 changes: 34 additions & 0 deletions lib/client/keyagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,40 @@ type LocalKeyAgent struct {
proxyHost string
}

// NewKeyStoreCertChecker returns a new certificate checker
// using trusted certs from key store
func NewKeyStoreCertChecker(keyStore LocalKeyStore) ssh.HostKeyCallback {
// CheckHostSignature checks if the given host key was signed by a Teleport
// certificate authority (CA) or a host certificate the user has seen before.
return func(addr string, remote net.Addr, key ssh.PublicKey) error {
certChecker := utils.CertChecker{
CertChecker: ssh.CertChecker{
IsHostAuthority: func(key ssh.PublicKey, addr string) bool {
keys, err := keyStore.GetKnownHostKeys("")
if err != nil {
log.Errorf("Unable to fetch certificate authorities: %v.", err)
return false
}
for i := range keys {
if sshutils.KeysEqual(key, keys[i]) {
return true
}
}
return false
},
},
FIPS: isFIPS(),
}
err := certChecker.CheckHostKey(addr, remote, key)
if err != nil {
log.Debugf("Host validation failed: %v.", err)
return trace.Wrap(err)
}
log.Debugf("Validated host %v.", addr)
return nil
}
}

// NewLocalAgent reads all Teleport certificates from disk (using FSLocalKeyStore),
// creates a LocalKeyAgent, loads all certificates into it, and returns the agent.
func NewLocalAgent(keyDir, proxyHost, username string, useLocalSSHAgent bool) (a *LocalKeyAgent, err error) {
Expand Down
Loading

0 comments on commit 9bdac2c

Please # to comment.