Я реализую SSH-клиент, который будет использовать аутентификацию агента (если она доступна) и откат к аутентификации с открытым ключом, если это не удастся. Я обнаружил, что могу сделать это, используя несколько подписывающих лиц, как показано ниже:
sshConfig := &ssh.ClientConfig{
User: getUsername(username, currentUser),
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Auth: []ssh.AuthMethod{
ssh.PublicKeysCallback(getSigners),
},
}
func getSigners() ([]ssh.Signer, error) {
signers := make([]ssh.Signer, 0)
currentUser, _ := user.Current()
if os.Getenv("SSH_AUTH_SOCK") != "" {
sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
if err == nil {
agentSigners, _ := agent.NewClient(sshAgent).Signers()
signers = append(signers, agentSigners...)
}
}
// default to id_rsa
keyPath := path.Join(path.Join(currentUser.HomeDir, ".ssh/id_rsa"))
buffer, errI := ioutil.ReadFile(keyPath)
if errI != nil {
fmt.Println(errI)
return signers, errI
}
block, _ := pem.Decode(buffer)
var key ssh.Signer
if strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED") {
fmt.Print("SSH Passphrase: ")
bytePassword, _ := terminal.ReadPassword(int(syscall.Stdin))
key, _ = ssh.ParsePrivateKeyWithPassphrase(buffer, bytePassword)
} else {
key, _ = ssh.ParsePrivateKey(buffer)
}
signers = append(signers, key)
return signers, nil
}
Проблема, связанная с этим методом, заключается в том, что он всегда запрашивает ключевую фразу, поскольку запрос на ключевую фразу возникает до того, как были предприняты какие-либо попытки аутентификации. Можно ли задержать расшифровку открытого ключа, чтобы можно было выполнить попытку аутентификации агента, прежде чем пользователю будет предложено ввести кодовую фразу?