Skip to content

Commit

Permalink
libgit2: change credentialsCallback logic
Browse files Browse the repository at this point in the history
This changes the logic of `credentialsCallback` so that it takes the
`allowedTypes` passed on by `git2go` into account. Reason for this
change is because this prepares it to work with `v33`, but also
because it can provide better guidance when `libgit2` has been
compiled with a different configuration, which e.g. doesn't
allow for "in-memory SSH keys".

Because `AuthOptions#Identity` now gets validated by the callback
and go-git does its own validaiton, the check has been removed
from `Validate` (and now does a simple check if the fields are set).

Signed-off-by: Hidde Beydals <hello@hidde.co>
  • Loading branch information
hiddeco committed Oct 25, 2021
1 parent 3c42c7e commit 35fcb23
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 27 deletions.
38 changes: 21 additions & 17 deletions pkg/git/libgit2/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"crypto/sha1"
"crypto/sha256"
"crypto/x509"
"fmt"
"hash"
"net"
"strings"
Expand Down Expand Up @@ -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
Expand Down
10 changes: 0 additions & 10 deletions pkg/git/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"fmt"
"net/url"

"golang.org/x/crypto/ssh"
v1 "k8s.io/api/core/v1"
)

Expand Down Expand Up @@ -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)
}
Expand Down

0 comments on commit 35fcb23

Please sign in to comment.