mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-04 18:59:08 +01:00
fix: add keys to agent if requested
This will add the keys to the ssh agent if requested by the ssh config file. It also adds the IdentityAgent keyword to override the environment variable.
This commit is contained in:
parent
a3de9768f2
commit
c46c2a926c
@ -66,7 +66,7 @@ func createDummySigner() ([]ssh.Signer, error) {
|
|||||||
// they were successes. An error in this function prevents any other
|
// they were successes. An error in this function prevents any other
|
||||||
// keys from being attempted. But if there's an error because of a dummy
|
// keys from being attempted. But if there's an error because of a dummy
|
||||||
// file, the library can still try again with a new key.
|
// file, the library can still try again with a new key.
|
||||||
func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords, passphrase string, authSockSignersExt []ssh.Signer) func() ([]ssh.Signer, error) {
|
func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords, passphrase string, authSockSignersExt []ssh.Signer, agentClient agent.ExtendedAgent) func() ([]ssh.Signer, error) {
|
||||||
var identityFiles []string
|
var identityFiles []string
|
||||||
existingKeys := make(map[string][]byte)
|
existingKeys := make(map[string][]byte)
|
||||||
|
|
||||||
@ -108,6 +108,25 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
|||||||
// skip this key and try with the next
|
// skip this key and try with the next
|
||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unencryptedPrivateKey, err := ssh.ParseRawPrivateKey(privateKey)
|
||||||
|
if _, ok := err.(*ssh.PassphraseMissingError); !ok {
|
||||||
|
// skip this key and try with the next
|
||||||
|
return createDummySigner()
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||||
|
if err == nil {
|
||||||
|
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||||
|
agentClient.Add(agent.AddedKey{
|
||||||
|
PrivateKey: unencryptedPrivateKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return []ssh.Signer{signer}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
signer, err := ssh.ParsePrivateKey(privateKey)
|
signer, err := ssh.ParsePrivateKey(privateKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return []ssh.Signer{signer}, err
|
return []ssh.Signer{signer}, err
|
||||||
@ -117,14 +136,34 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
|||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unencryptedPrivateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKey, []byte(passphrase))
|
||||||
|
if err != x509.IncorrectPasswordError && err.Error() != "bcrypt_pbkdf: empty password" {
|
||||||
|
// skip this key and try with the next
|
||||||
|
return createDummySigner()
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||||
|
if err == nil {
|
||||||
|
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||||
|
agentClient.Add(agent.AddedKey{
|
||||||
|
PrivateKey: unencryptedPrivateKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return []ssh.Signer{signer}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(passphrase))
|
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(passphrase))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
log.Printf("with passphrase %v\n", signer.PublicKey().Marshal())
|
||||||
return []ssh.Signer{signer}, err
|
return []ssh.Signer{signer}, err
|
||||||
}
|
}
|
||||||
if err != x509.IncorrectPasswordError && err.Error() != "bcrypt_pbkdf: empty password" {
|
if err != x509.IncorrectPasswordError && err.Error() != "bcrypt_pbkdf: empty password" {
|
||||||
// skip this key and try with the next
|
// skip this key and try with the next
|
||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// batch mode deactivates user input
|
// batch mode deactivates user input
|
||||||
if sshKeywords.BatchMode {
|
if sshKeywords.BatchMode {
|
||||||
@ -145,12 +184,33 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *SshKeywords,
|
|||||||
// trying keys
|
// trying keys
|
||||||
return nil, UserInputCancelError{Err: err}
|
return nil, UserInputCancelError{Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unencryptedPrivateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKey, []byte([]byte(response.Text)))
|
||||||
|
if err != nil {
|
||||||
|
// skip this key and try with the next
|
||||||
|
return createDummySigner()
|
||||||
|
}
|
||||||
|
signer, err = ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
// skip this key and try with the next
|
||||||
|
return createDummySigner()
|
||||||
|
}
|
||||||
|
if sshKeywords.AddKeysToAgent && agentClient != nil {
|
||||||
|
agentClient.Add(agent.AddedKey{
|
||||||
|
PrivateKey: unencryptedPrivateKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return []ssh.Signer{signer}, err
|
||||||
|
|
||||||
|
/*
|
||||||
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(response.Text))
|
signer, err = ssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(response.Text))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// skip this key and try with the next
|
// skip this key and try with the next
|
||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
|
log.Printf("with passphrase %v\n", signer.PublicKey().Marshal())
|
||||||
return []ssh.Signer{signer}, err
|
return []ssh.Signer{signer}, err
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +600,7 @@ func DialContext(ctx context.Context, network string, addr string, config *ssh.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDisplayName string, sshAuthSock string) (*ssh.Client, error) {
|
func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDisplayName string, sshAuthSock string) (*ssh.Client, error) {
|
||||||
sshConfigKeywords, err := findSshConfigKeywords(opts.SSHHost)
|
sshConfigKeywords, err := findSshConfigKeywords(opts.SSHHost, sshAuthSock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -550,16 +610,17 @@ func ConnectToClient(connCtx context.Context, opts *sstore.SSHOpts, remoteDispla
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := net.Dial("unix", sshAuthSock)
|
conn, err := net.Dial("unix", sshKeywords.IdentityAgent)
|
||||||
var authSockSigners []ssh.Signer
|
var authSockSigners []ssh.Signer
|
||||||
|
var agentClient agent.ExtendedAgent
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to open SSH_AUTH_SOCK: %v", err)
|
log.Printf("Failed to open Identity Agent Socket: %v", err)
|
||||||
} else {
|
} else {
|
||||||
agentClient := agent.NewClient(conn)
|
agentClient = agent.NewClient(conn)
|
||||||
authSockSigners, _ = agentClient.Signers()
|
authSockSigners, _ = agentClient.Signers()
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyCallback := ssh.PublicKeysCallback(createPublicKeyCallback(connCtx, sshKeywords, opts.SSHPassword, authSockSigners))
|
publicKeyCallback := ssh.PublicKeysCallback(createPublicKeyCallback(connCtx, sshKeywords, opts.SSHPassword, authSockSigners, agentClient))
|
||||||
keyboardInteractive := ssh.KeyboardInteractive(createCombinedKbdInteractiveChallenge(connCtx, opts.SSHPassword, remoteDisplayName))
|
keyboardInteractive := ssh.KeyboardInteractive(createCombinedKbdInteractiveChallenge(connCtx, opts.SSHPassword, remoteDisplayName))
|
||||||
passwordCallback := ssh.PasswordCallback(createCombinedPasswordCallbackPrompt(connCtx, opts.SSHPassword, remoteDisplayName))
|
passwordCallback := ssh.PasswordCallback(createCombinedPasswordCallbackPrompt(connCtx, opts.SSHPassword, remoteDisplayName))
|
||||||
|
|
||||||
@ -622,6 +683,8 @@ type SshKeywords struct {
|
|||||||
PasswordAuthentication bool
|
PasswordAuthentication bool
|
||||||
KbdInteractiveAuthentication bool
|
KbdInteractiveAuthentication bool
|
||||||
PreferredAuthentications []string
|
PreferredAuthentications []string
|
||||||
|
AddKeysToAgent bool
|
||||||
|
IdentityAgent string
|
||||||
}
|
}
|
||||||
|
|
||||||
func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*SshKeywords, error) {
|
func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*SshKeywords, error) {
|
||||||
@ -671,6 +734,8 @@ func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*Ssh
|
|||||||
sshKeywords.PasswordAuthentication = configKeywords.PasswordAuthentication
|
sshKeywords.PasswordAuthentication = configKeywords.PasswordAuthentication
|
||||||
sshKeywords.KbdInteractiveAuthentication = configKeywords.KbdInteractiveAuthentication
|
sshKeywords.KbdInteractiveAuthentication = configKeywords.KbdInteractiveAuthentication
|
||||||
sshKeywords.PreferredAuthentications = configKeywords.PreferredAuthentications
|
sshKeywords.PreferredAuthentications = configKeywords.PreferredAuthentications
|
||||||
|
sshKeywords.AddKeysToAgent = configKeywords.AddKeysToAgent
|
||||||
|
sshKeywords.IdentityAgent = configKeywords.IdentityAgent
|
||||||
|
|
||||||
return sshKeywords, nil
|
return sshKeywords, nil
|
||||||
}
|
}
|
||||||
@ -678,7 +743,7 @@ func combineSshKeywords(opts *sstore.SSHOpts, configKeywords *SshKeywords) (*Ssh
|
|||||||
// note that a `var == "yes"` will default to false
|
// note that a `var == "yes"` will default to false
|
||||||
// but `var != "no"` will default to true
|
// but `var != "no"` will default to true
|
||||||
// when given unexpected strings
|
// when given unexpected strings
|
||||||
func findSshConfigKeywords(hostPattern string) (*SshKeywords, error) {
|
func findSshConfigKeywords(hostPattern string, sshAuthSock string) (*SshKeywords, error) {
|
||||||
ssh_config.ReloadConfigs()
|
ssh_config.ReloadConfigs()
|
||||||
sshKeywords := &SshKeywords{}
|
sshKeywords := &SshKeywords{}
|
||||||
var err error
|
var err error
|
||||||
@ -733,5 +798,21 @@ func findSshConfigKeywords(hostPattern string) (*SshKeywords, error) {
|
|||||||
}
|
}
|
||||||
sshKeywords.PreferredAuthentications = strings.Split(preferredAuthenticationsRaw, ",")
|
sshKeywords.PreferredAuthentications = strings.Split(preferredAuthenticationsRaw, ",")
|
||||||
|
|
||||||
|
addKeysToAgentRaw, err := ssh_config.GetStrict(hostPattern, "AddKeysToAgent")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sshKeywords.AddKeysToAgent = (strings.ToLower(addKeysToAgentRaw) == "yes")
|
||||||
|
|
||||||
|
identityAgentRaw, err := ssh_config.GetStrict(hostPattern, "IdentityAgent")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if identityAgentRaw == "" {
|
||||||
|
sshKeywords.IdentityAgent = sshAuthSock
|
||||||
|
} else {
|
||||||
|
sshKeywords.IdentityAgent = identityAgentRaw
|
||||||
|
}
|
||||||
|
|
||||||
return sshKeywords, nil
|
return sshKeywords, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user