78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package ssh
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
"path"
|
|
"path/filepath"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
BackendName = "ssh"
|
|
|
|
HostKeyPolicyStrict HostKeyPolicy = "strict"
|
|
HostKeyPolicyAcceptNew HostKeyPolicy = "accept-new"
|
|
HostKeyPolicyOff HostKeyPolicy = "off"
|
|
)
|
|
|
|
type HostKeyPolicy string
|
|
|
|
type Options struct {
|
|
Host string
|
|
User string
|
|
Port int
|
|
Root string
|
|
KeyFile string
|
|
KnownHosts string
|
|
HostKeyPolicy HostKeyPolicy
|
|
}
|
|
|
|
func (o Options) normalized() (Options, error) {
|
|
if o.Host == "" {
|
|
return Options{}, fmt.Errorf("host is required")
|
|
}
|
|
if o.User == "" {
|
|
current, err := user.Current()
|
|
if err != nil || current.Username == "" {
|
|
return Options{}, fmt.Errorf("user is required when current OS user cannot be determined")
|
|
}
|
|
o.User = current.Username
|
|
}
|
|
if o.Port == 0 {
|
|
o.Port = 22
|
|
}
|
|
if o.Port < 1 || o.Port > 65535 {
|
|
return Options{}, fmt.Errorf("port must be between 1 and 65535")
|
|
}
|
|
if o.Root == "" {
|
|
return Options{}, fmt.Errorf("path is required")
|
|
}
|
|
o.Root = path.Clean(o.Root)
|
|
if o.HostKeyPolicy == "" {
|
|
o.HostKeyPolicy = HostKeyPolicyAcceptNew
|
|
}
|
|
switch o.HostKeyPolicy {
|
|
case HostKeyPolicyStrict, HostKeyPolicyAcceptNew, HostKeyPolicyOff:
|
|
default:
|
|
return Options{}, fmt.Errorf("host_key_policy must be strict, accept-new, or off")
|
|
}
|
|
if o.KnownHosts == "" && o.HostKeyPolicy != HostKeyPolicyOff {
|
|
o.KnownHosts = defaultKnownHostsPath()
|
|
}
|
|
return o, nil
|
|
}
|
|
|
|
func (o Options) address() string {
|
|
return o.Host + ":" + strconv.Itoa(o.Port)
|
|
}
|
|
|
|
func defaultKnownHostsPath() string {
|
|
home, err := os.UserHomeDir()
|
|
if err != nil || home == "" {
|
|
return ""
|
|
}
|
|
return filepath.Join(home, ".ssh", "known_hosts")
|
|
}
|