certimate/pkg/utils/ssh/client.go
2025-09-09 13:56:07 +08:00

60 lines
2.0 KiB
Go

package ssh
import (
"fmt"
"net"
"strconv"
"strings"
"golang.org/x/crypto/ssh"
)
func NewClient(conn net.Conn, host string, port int, username string) (*ssh.Client, error) {
authentications := make([]ssh.AuthMethod, 0)
return newClientWithAuthMethods(conn, host, port, username, authentications)
}
func NewClientWithPassword(conn net.Conn, host string, port int, username string, password string) (*ssh.Client, error) {
authentications := make([]ssh.AuthMethod, 0)
authentications = append(authentications, ssh.Password(password))
authentications = append(authentications, ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) ([]string, error) {
if len(questions) == 1 {
return []string{password}, nil
}
return nil, fmt.Errorf("unexpected keyboard interactive question [%s]", strings.Join(questions, ", "))
}))
return newClientWithAuthMethods(conn, host, port, username, authentications)
}
func NewClientWithKey(conn net.Conn, host string, port int, username string, key, keyPassphrase string) (*ssh.Client, error) {
var signer ssh.Signer
var err error
if keyPassphrase != "" {
signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(key), []byte(keyPassphrase))
} else {
signer, err = ssh.ParsePrivateKey([]byte(key))
}
if err != nil {
return nil, err
}
authentications := make([]ssh.AuthMethod, 0)
authentications = append(authentications, ssh.PublicKeys(signer))
return newClientWithAuthMethods(conn, host, port, username, authentications)
}
func newClientWithAuthMethods(conn net.Conn, host string, port int, username string, authMethods []ssh.AuthMethod) (*ssh.Client, error) {
addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
sshConn, chans, reqs, err := ssh.NewClientConn(conn, addr, &ssh.ClientConfig{
User: username,
Auth: authMethods,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
})
if err != nil {
return nil, err
}
return ssh.NewClient(sshConn, chans, reqs), nil
}