Files
deploy/util/git/ssh.go
T
2026-05-22 15:13:00 +05:30

85 lines
2.8 KiB
Go

package git
import (
"crypto/fips140"
"fmt"
gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
"golang.org/x/crypto/ssh"
)
// SupportedSSHKeyExchangeAlgorithms is a list of all currently supported algorithms for SSH key exchange
// Unfortunately, crypto/ssh does not offer public constants or list for
// this.
var SupportedSSHKeyExchangeAlgorithms = []string{
"curve25519-sha256",
"[email protected]",
"ecdh-sha2-nistp256",
"ecdh-sha2-nistp384",
"ecdh-sha2-nistp521",
"diffie-hellman-group-exchange-sha256",
"diffie-hellman-group14-sha256",
"diffie-hellman-group14-sha1",
}
// SupportedFIPSCompliantSSHKeyExchangeAlgorithms is a list of all currently supported algorithms for SSH key exchange
// that are FIPS compliant
var SupportedFIPSCompliantSSHKeyExchangeAlgorithms = []string{
"ecdh-sha2-nistp256",
"ecdh-sha2-nistp384",
"ecdh-sha2-nistp521",
"diffie-hellman-group-exchange-sha256",
"diffie-hellman-group14-sha256",
}
// PublicKeysWithOptions is an auth method for go-git's SSH client that
// inherits from PublicKeys, but provides the possibility to override
// some client options.
type PublicKeysWithOptions struct {
KexAlgorithms []string
// HostKeyAlgorithms restricts the host key algorithms advertised during
// the SSH handshake to those known for the target host. go-git v5.16+
// only auto-configures this when the user's AuthMethod does not set a
// HostKeyCallback; since we always set one, we must populate this
// ourselves or the handshake can fail with "knownhosts: key mismatch"
// when the server offers a key of a type that isn't in known_hosts.
// See go-git/go-git#1551.
HostKeyAlgorithms []string
gitssh.PublicKeys
}
// Name returns the name of the auth method
func (a *PublicKeysWithOptions) Name() string {
return gitssh.PublicKeysName
}
// String returns the configured user and auth method name as string
func (a *PublicKeysWithOptions) String() string {
return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
}
// ClientConfig returns a custom SSH client configuration
func (a *PublicKeysWithOptions) ClientConfig() (*ssh.ClientConfig, error) {
// Algorithms used for kex can be configured
var kexAlgos []string
if len(a.KexAlgorithms) > 0 {
kexAlgos = a.KexAlgorithms
} else {
kexAlgos = getDefaultSSHKeyExchangeAlgorithms()
}
config := ssh.Config{KeyExchanges: kexAlgos}
opts := &ssh.ClientConfig{Config: config, User: a.User, Auth: []ssh.AuthMethod{ssh.PublicKeys(a.Signer)}}
if len(a.HostKeyAlgorithms) > 0 {
opts.HostKeyAlgorithms = a.HostKeyAlgorithms
}
return a.SetHostKeyCallback(opts)
}
// getDefaultSSHKeyExchangeAlgorithms returns the default key exchange algorithms to be used
func getDefaultSSHKeyExchangeAlgorithms() []string {
if fips140.Enabled() {
return SupportedFIPSCompliantSSHKeyExchangeAlgorithms
}
return SupportedSSHKeyExchangeAlgorithms
}