diff --git a/pkg/git/libgit2/transport.go b/pkg/git/libgit2/transport.go index c9fb56c52..83d9107ec 100644 --- a/pkg/git/libgit2/transport.go +++ b/pkg/git/libgit2/transport.go @@ -23,6 +23,7 @@ import ( "crypto/sha1" "crypto/sha256" "crypto/x509" + "fmt" "hash" "net" "strings" @@ -52,29 +53,32 @@ func RemoteCallbacks(opts *git.AuthOptions) git2go.RemoteCallbacks { } // credentialsCallback constructs CredentialsCallbacks with the given options -// for git.Transport if the given opts is not nil, and returns the result. +// for git.Transport, and returns the result. func credentialsCallback(opts *git.AuthOptions) git2go.CredentialsCallback { - switch opts.Transport { - case git.HTTP: - if opts.Username != "" { - return func(u string, user string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { - return git2go.NewCredentialUsername(opts.Username) + return func(url string, username string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { + if allowedTypes&(git2go.CredentialTypeSSHKey|git2go.CredentialTypeSSHCustom|git2go.CredentialTypeSSHMemory) != 0 { + var ( + signer ssh.Signer + err error + ) + if opts.Password != "" { + signer, err = ssh.ParsePrivateKeyWithPassphrase(opts.Identity, []byte(opts.Password)) + } else { + signer, err = ssh.ParsePrivateKey(opts.Identity) } - } - case git.HTTPS: - if opts.Username != "" && opts.Password != "" { - return func(u string, user string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { - return git2go.NewCredentialUserpassPlaintext(opts.Username, opts.Password) + if err != nil { + return nil, err } + return git2go.NewCredentialSSHKeyFromSigner(opts.Username, signer) } - case git.SSH: - if len(opts.Identity) > 0 { - return func(u string, user string, allowedTypes git2go.CredentialType) (*git2go.Credential, error) { - return git2go.NewCredentialSSHKeyFromMemory(opts.Username, "", string(opts.Identity), opts.Password) - } + if (allowedTypes & git2go.CredentialTypeUserpassPlaintext) != 0 { + return git2go.NewCredentialUserpassPlaintext(opts.Username, opts.Password) } + if (allowedTypes & git2go.CredentialTypeUsername) != 0 { + return git2go.NewCredentialUsername(opts.Username) + } + return nil, fmt.Errorf("unknown credential type %+v", allowedTypes) } - return nil } // certificateCallback constructs CertificateCallback with the given options diff --git a/pkg/git/options.go b/pkg/git/options.go index 1134c79c8..bc9436087 100644 --- a/pkg/git/options.go +++ b/pkg/git/options.go @@ -20,7 +20,6 @@ import ( "fmt" "net/url" - "golang.org/x/crypto/ssh" v1 "k8s.io/api/core/v1" ) @@ -82,15 +81,6 @@ func (o AuthOptions) Validate() error { if len(o.Identity) == 0 { return fmt.Errorf("invalid '%s' auth option: 'identity' is required", o.Transport) } - var err error - if o.Password != "" { - _, err = ssh.ParsePrivateKeyWithPassphrase(o.Identity, []byte(o.Password)) - } else { - _, err = ssh.ParsePrivateKey(o.Identity) - } - if err != nil { - return fmt.Errorf("invalid '%s' auth option 'identity': %w", o.Transport, err) - } if len(o.KnownHosts) == 0 { return fmt.Errorf("invalid '%s' auth option: 'known_hosts' is required", o.Transport) } diff --git a/pkg/git/options_test.go b/pkg/git/options_test.go index 57d7dec24..3ab3ee59a 100644 --- a/pkg/git/options_test.go +++ b/pkg/git/options_test.go @@ -113,23 +113,6 @@ func TestAuthOptions_Validate(t *testing.T) { }, wantErr: "invalid 'ssh' auth option: 'identity' is required", }, - { - name: "SSH transport requires valid identity", - opts: AuthOptions{ - Transport: SSH, - Identity: []byte("malformed"), - }, - wantErr: "invalid 'ssh' auth option 'identity': ssh: no key found", - }, - { - name: "SSH transport requires valid identity password", - opts: AuthOptions{ - Transport: SSH, - Identity: []byte(privateKeyPassphraseFixture), - Password: "invalid", - }, - wantErr: "invalid 'ssh' auth option 'identity': x509: decryption password incorrect", - }, { name: "SSH transport requires known_hosts", opts: AuthOptions{