github.com/argoproj/argo-cd/v3@v3.2.1/util/git/ssh.go (about)

     1  package git
     2  
     3  import (
     4  	"crypto/fips140"
     5  	"fmt"
     6  
     7  	gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
     8  	"golang.org/x/crypto/ssh"
     9  )
    10  
    11  // SupportedSSHKeyExchangeAlgorithms is a list of all currently supported algorithms for SSH key exchange
    12  // Unfortunately, crypto/ssh does not offer public constants or list for
    13  // this.
    14  var SupportedSSHKeyExchangeAlgorithms = []string{
    15  	"curve25519-sha256",
    16  	"curve25519-sha256@libssh.org",
    17  	"ecdh-sha2-nistp256",
    18  	"ecdh-sha2-nistp384",
    19  	"ecdh-sha2-nistp521",
    20  	"diffie-hellman-group-exchange-sha256",
    21  	"diffie-hellman-group14-sha256",
    22  	"diffie-hellman-group14-sha1",
    23  }
    24  
    25  // SupportedFIPSCompliantSSHKeyExchangeAlgorithms is a list of all currently supported algorithms for SSH key exchange
    26  // that are FIPS compliant
    27  var SupportedFIPSCompliantSSHKeyExchangeAlgorithms = []string{
    28  	"ecdh-sha2-nistp256",
    29  	"ecdh-sha2-nistp384",
    30  	"ecdh-sha2-nistp521",
    31  	"diffie-hellman-group-exchange-sha256",
    32  	"diffie-hellman-group14-sha256",
    33  }
    34  
    35  // PublicKeysWithOptions is an auth method for go-git's SSH client that
    36  // inherits from PublicKeys, but provides the possibility to override
    37  // some client options.
    38  type PublicKeysWithOptions struct {
    39  	KexAlgorithms []string
    40  	gitssh.PublicKeys
    41  }
    42  
    43  // Name returns the name of the auth method
    44  func (a *PublicKeysWithOptions) Name() string {
    45  	return gitssh.PublicKeysName
    46  }
    47  
    48  // String returns the configured user and auth method name as string
    49  func (a *PublicKeysWithOptions) String() string {
    50  	return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
    51  }
    52  
    53  // ClientConfig returns a custom SSH client configuration
    54  func (a *PublicKeysWithOptions) ClientConfig() (*ssh.ClientConfig, error) {
    55  	// Algorithms used for kex can be configured
    56  	var kexAlgos []string
    57  	if len(a.KexAlgorithms) > 0 {
    58  		kexAlgos = a.KexAlgorithms
    59  	} else {
    60  		kexAlgos = getDefaultSSHKeyExchangeAlgorithms()
    61  	}
    62  	config := ssh.Config{KeyExchanges: kexAlgos}
    63  	opts := &ssh.ClientConfig{Config: config, User: a.User, Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)}}
    64  	return a.SetHostKeyCallback(opts)
    65  }
    66  
    67  // getDefaultSSHKeyExchangeAlgorithms returns the default key exchange algorithms to be used
    68  func getDefaultSSHKeyExchangeAlgorithms() []string {
    69  	if fips140.Enabled() {
    70  		return SupportedFIPSCompliantSSHKeyExchangeAlgorithms
    71  	}
    72  	return SupportedSSHKeyExchangeAlgorithms
    73  }