(connCtx context.Context, sshKeywords *wconfig.ConnKeywords, debugInfo *ConnectionDebugInfo)
| 755 | } |
| 756 | |
| 757 | func createClientConfig(connCtx context.Context, sshKeywords *wconfig.ConnKeywords, debugInfo *ConnectionDebugInfo) (*ssh.ClientConfig, error) { |
| 758 | chosenUser := utilfn.SafeDeref(sshKeywords.SshUser) |
| 759 | chosenHostName := utilfn.SafeDeref(sshKeywords.SshHostName) |
| 760 | chosenPort := utilfn.SafeDeref(sshKeywords.SshPort) |
| 761 | remoteName := xknownhosts.Normalize(chosenHostName + ":" + chosenPort) |
| 762 | if chosenUser != "" { |
| 763 | remoteName = chosenUser + "@" + remoteName |
| 764 | } |
| 765 | |
| 766 | var authSockSigners []ssh.Signer |
| 767 | var agentClient agent.ExtendedAgent |
| 768 | |
| 769 | // IdentitiesOnly indicates that only the keys listed in the identity and certificate files or passed as arguments should be used, even if there are matches in the SSH Agent, PKCS11Provider, or SecurityKeyProvider. See https://man.openbsd.org/ssh_config#IdentitiesOnly |
| 770 | // TODO: Update if we decide to support PKCS11Provider and SecurityKeyProvider |
| 771 | agentPath := strings.TrimSpace(utilfn.SafeDeref(sshKeywords.SshIdentityAgent)) |
| 772 | if !utilfn.SafeDeref(sshKeywords.SshIdentitiesOnly) && agentPath != "" { |
| 773 | conn, err := dialIdentityAgent(agentPath) |
| 774 | if err != nil { |
| 775 | log.Printf("Failed to open Identity Agent Socket %q: %v", agentPath, err) |
| 776 | } else { |
| 777 | agentClient = agent.NewClient(conn) |
| 778 | authSockSigners, _ = agentClient.Signers() |
| 779 | } |
| 780 | } |
| 781 | |
| 782 | var sshPassword *string |
| 783 | if sshKeywords.SshPasswordSecretName != nil && *sshKeywords.SshPasswordSecretName != "" { |
| 784 | secretName := *sshKeywords.SshPasswordSecretName |
| 785 | password, exists, err := secretstore.GetSecret(secretName) |
| 786 | if err != nil { |
| 787 | return nil, utilds.Errorf(ConnErrCode_SecretStore, "error retrieving ssh:passwordsecretname %q: %w", secretName, err) |
| 788 | } |
| 789 | if !exists { |
| 790 | return nil, utilds.Errorf(ConnErrCode_SecretNotFound, "ssh:passwordsecretname %q not found in secret store", secretName) |
| 791 | } |
| 792 | blocklogger.Infof(connCtx, "[conndebug] successfully retrieved ssh:passwordsecretname %q from secret store\n", secretName) |
| 793 | sshPassword = &password |
| 794 | } |
| 795 | |
| 796 | publicKeyCallback := ssh.PublicKeysCallback(createPublicKeyCallback(connCtx, sshKeywords, authSockSigners, agentClient, debugInfo)) |
| 797 | keyboardInteractive := ssh.KeyboardInteractive(createInteractiveKbdInteractiveChallenge(connCtx, remoteName, debugInfo)) |
| 798 | passwordCallback := ssh.PasswordCallback(createPasswordCallbackPrompt(connCtx, remoteName, sshPassword, debugInfo)) |
| 799 | |
| 800 | // exclude gssapi-with-mic and hostbased until implemented |
| 801 | authMethodMap := map[string]ssh.AuthMethod{ |
| 802 | "publickey": ssh.RetryableAuthMethod(publicKeyCallback, len(sshKeywords.SshIdentityFile)+len(authSockSigners)), |
| 803 | "keyboard-interactive": ssh.RetryableAuthMethod(keyboardInteractive, 1), |
| 804 | "password": ssh.RetryableAuthMethod(passwordCallback, 1), |
| 805 | } |
| 806 | |
| 807 | // note: batch mode turns off interactive input |
| 808 | authMethodActiveMap := map[string]bool{ |
| 809 | "publickey": utilfn.SafeDeref(sshKeywords.SshPubkeyAuthentication), |
| 810 | "keyboard-interactive": utilfn.SafeDeref(sshKeywords.SshKbdInteractiveAuthentication) && !utilfn.SafeDeref(sshKeywords.SshBatchMode), |
| 811 | "password": utilfn.SafeDeref(sshKeywords.SshPasswordAuthentication) && !utilfn.SafeDeref(sshKeywords.SshBatchMode), |
| 812 | } |
| 813 | |
| 814 | var authMethods []ssh.AuthMethod |
no test coverage detected