// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ssh

import (
	"bytes"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/hashicorp/terraform/internal/communicator/shared"
	sshagent "github.com/xanzy/ssh-agent"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/gocty"
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/agent"
	"golang.org/x/crypto/ssh/knownhosts"
)

const (
	// DefaultUser is used if there is no user given
	DefaultUser = "root"

	// DefaultPort is used if there is no port given
	DefaultPort = 22

	// DefaultUnixScriptPath is used as the path to copy the file to
	// for remote execution on unix if not provided otherwise.
	DefaultUnixScriptPath = "/tmp/terraform_%RAND%.sh"
	// DefaultWindowsScriptPath is used as the path to copy the file to
	// for remote execution on windows if not provided otherwise.
	DefaultWindowsScriptPath = "C:/windows/temp/terraform_%RAND%.cmd"

	// DefaultTimeout is used if there is no timeout given
	DefaultTimeout = 5 * time.Minute

	// TargetPlatformUnix used for cleaner code, and is used if no target platform has been specified
	TargetPlatformUnix = "unix"
	//TargetPlatformWindows used for cleaner code
	TargetPlatformWindows = "windows"
)

// connectionInfo is decoded from the ConnInfo of the resource. These are the
// only keys we look at. If a PrivateKey is given, that is used instead
// of a password.
type connectionInfo struct {
	User           string
	Password       string
	PrivateKey     string
	Certificate    string
	Host           string
	HostKey        string
	Port           uint16
	Agent          bool
	ScriptPath     string
	TargetPlatform string
	Timeout        string
	TimeoutVal     time.Duration

	ProxyScheme       string
	ProxyHost         string
	ProxyPort         uint16
	ProxyUserName     string
	ProxyUserPassword string

	BastionUser        string
	BastionPassword    string
	BastionPrivateKey  string
	BastionCertificate string
	BastionHost        string
	BastionHostKey     string
	BastionPort        uint16

	AgentIdentity string
}

// decodeConnInfo decodes the given cty.Value using the same behavior as the
// lgeacy mapstructure decoder in order to preserve as much of the existing
// logic as possible for compatibility.
func decodeConnInfo(v cty.Value) (*connectionInfo, error) {
	connInfo := &connectionInfo{}
	if v.IsNull() {
		return connInfo, nil
	}

	for k, v := range v.AsValueMap() {
		if v.IsNull() {
			continue
		}

		switch k {
		case "user":
			connInfo.User = v.AsString()
		case "password":
			connInfo.Password = v.AsString()
		case "private_key":
			connInfo.PrivateKey = v.AsString()
		case "certificate":
			connInfo.Certificate = v.AsString()
		case "host":
			connInfo.Host = v.AsString()
		case "host_key":
			connInfo.HostKey = v.AsString()
		case "port":
			if err := gocty.FromCtyValue(v, &connInfo.Port); err != nil {
				return nil, err
			}
		case "agent":
			connInfo.Agent = v.True()
		case "script_path":
			connInfo.ScriptPath = v.AsString()
		case "target_platform":
			connInfo.TargetPlatform = v.AsString()
		case "timeout":
			connInfo.Timeout = v.AsString()
		case "proxy_scheme":
			connInfo.ProxyScheme = v.AsString()
		case "proxy_host":
			connInfo.ProxyHost = v.AsString()
		case "proxy_port":
			if err := gocty.FromCtyValue(v, &connInfo.ProxyPort); err != nil {
				return nil, err
			}
		case "proxy_user_name":
			connInfo.ProxyUserName = v.AsString()
		case "proxy_user_password":
			connInfo.ProxyUserPassword = v.AsString()
		case "bastion_user":
			connInfo.BastionUser = v.AsString()
		case "bastion_password":
			connInfo.BastionPassword = v.AsString()
		case "bastion_private_key":
			connInfo.BastionPrivateKey = v.AsString()
		case "bastion_certificate":
			connInfo.BastionCertificate = v.AsString()
		case "bastion_host":
			connInfo.BastionHost = v.AsString()
		case "bastion_host_key":
			connInfo.BastionHostKey = v.AsString()
		case "bastion_port":
			if err := gocty.FromCtyValue(v, &connInfo.BastionPort); err != nil {
				return nil, err
			}
		case "agent_identity":
			connInfo.AgentIdentity = v.AsString()
		}
	}
	return connInfo, nil
}

// parseConnectionInfo is used to convert the raw configuration into the
// *connectionInfo struct.
func parseConnectionInfo(v cty.Value) (*connectionInfo, error) {
	v, err := shared.ConnectionBlockSupersetSchema.CoerceValue(v)
	if err != nil {
		return nil, err
	}

	connInfo, err := decodeConnInfo(v)
	if err != nil {
		return nil, err
	}

	// To default Agent to true, we need to check the raw string, since the
	// decoded boolean can't represent "absence of config".
	//
	// And if SSH_AUTH_SOCK is not set, there's no agent to connect to, so we
	// shouldn't try.
	agent := v.GetAttr("agent")
	if agent.IsNull() && os.Getenv("SSH_AUTH_SOCK") != "" {
		connInfo.Agent = true
	}

	if connInfo.User == "" {
		connInfo.User = DefaultUser
	}

	// Check if host is empty.
	// Otherwise return error.
	if connInfo.Host == "" {
		return nil, fmt.Errorf("host for provisioner cannot be empty")
	}

	// Format the host if needed.
	// Needed for IPv6 support.
	connInfo.Host = shared.IpFormat(connInfo.Host)

	if connInfo.Port == 0 {
		connInfo.Port = DefaultPort
	}
	// Set default targetPlatform to unix if it's empty
	if connInfo.TargetPlatform == "" {
		connInfo.TargetPlatform = TargetPlatformUnix
	} else if connInfo.TargetPlatform != TargetPlatformUnix && connInfo.TargetPlatform != TargetPlatformWindows {
		return nil, fmt.Errorf("target_platform for provisioner has to be either %s or %s", TargetPlatformUnix, TargetPlatformWindows)
	}
	// Choose an appropriate default script path based on the target platform. There is no single
	// suitable default script path which works on both UNIX and Windows targets.
	if connInfo.ScriptPath == "" && connInfo.TargetPlatform == TargetPlatformUnix {
		connInfo.ScriptPath = DefaultUnixScriptPath
	}
	if connInfo.ScriptPath == "" && connInfo.TargetPlatform == TargetPlatformWindows {
		connInfo.ScriptPath = DefaultWindowsScriptPath
	}
	if connInfo.Timeout != "" {
		connInfo.TimeoutVal = safeDuration(connInfo.Timeout, DefaultTimeout)
	} else {
		connInfo.TimeoutVal = DefaultTimeout
	}

	// Default all bastion config attrs to their non-bastion counterparts
	if connInfo.BastionHost != "" {
		// Format the bastion host if needed.
		// Needed for IPv6 support.
		connInfo.BastionHost = shared.IpFormat(connInfo.BastionHost)

		if connInfo.BastionUser == "" {
			connInfo.BastionUser = connInfo.User
		}
		if connInfo.BastionPassword == "" {
			connInfo.BastionPassword = connInfo.Password
		}
		if connInfo.BastionPrivateKey == "" {
			connInfo.BastionPrivateKey = connInfo.PrivateKey
		}
		if connInfo.BastionCertificate == "" {
			connInfo.BastionCertificate = connInfo.Certificate
		}
		if connInfo.BastionPort == 0 {
			connInfo.BastionPort = connInfo.Port
		}
	}

	return connInfo, nil
}

// safeDuration returns either the parsed duration or a default value
func safeDuration(dur string, defaultDur time.Duration) time.Duration {
	d, err := time.ParseDuration(dur)
	if err != nil {
		log.Printf("Invalid duration '%s', using default of %s", dur, defaultDur)
		return defaultDur
	}
	return d
}

// prepareSSHConfig is used to turn the *ConnectionInfo provided into a
// usable *SSHConfig for client initialization.
func prepareSSHConfig(connInfo *connectionInfo) (*sshConfig, error) {
	sshAgent, err := connectToAgent(connInfo)
	if err != nil {
		return nil, err
	}

	host := fmt.Sprintf("%s:%d", connInfo.Host, connInfo.Port)

	sshConf, err := buildSSHClientConfig(sshClientConfigOpts{
		user:        connInfo.User,
		host:        host,
		privateKey:  connInfo.PrivateKey,
		password:    connInfo.Password,
		hostKey:     connInfo.HostKey,
		certificate: connInfo.Certificate,
		sshAgent:    sshAgent,
	})
	if err != nil {
		return nil, err
	}

	var p *proxyInfo

	if connInfo.ProxyHost != "" {
		p = newProxyInfo(
			fmt.Sprintf("%s:%d", connInfo.ProxyHost, connInfo.ProxyPort),
			connInfo.ProxyScheme,
			connInfo.ProxyUserName,
			connInfo.ProxyUserPassword,
		)
	}

	connectFunc := ConnectFunc("tcp", host, p)

	var bastionConf *ssh.ClientConfig
	if connInfo.BastionHost != "" {
		bastionHost := fmt.Sprintf("%s:%d", connInfo.BastionHost, connInfo.BastionPort)

		bastionConf, err = buildSSHClientConfig(sshClientConfigOpts{
			user:        connInfo.BastionUser,
			host:        bastionHost,
			privateKey:  connInfo.BastionPrivateKey,
			password:    connInfo.BastionPassword,
			hostKey:     connInfo.HostKey,
			certificate: connInfo.BastionCertificate,
			sshAgent:    sshAgent,
		})
		if err != nil {
			return nil, err
		}

		connectFunc = BastionConnectFunc("tcp", bastionHost, bastionConf, "tcp", host, p)
	}

	config := &sshConfig{
		config:     sshConf,
		connection: connectFunc,
		sshAgent:   sshAgent,
	}
	return config, nil
}

type sshClientConfigOpts struct {
	privateKey  string
	password    string
	sshAgent    *sshAgent
	certificate string
	user        string
	host        string
	hostKey     string
}

func buildSSHClientConfig(opts sshClientConfigOpts) (*ssh.ClientConfig, error) {
	hkCallback := ssh.InsecureIgnoreHostKey()

	if opts.hostKey != "" {
		// The knownhosts package only takes paths to files, but terraform
		// generally wants to handle config data in-memory. Rather than making
		// the known_hosts file an exception, write out the data to a temporary
		// file to create the HostKeyCallback.
		tf, err := ioutil.TempFile("", "tf-known_hosts")
		if err != nil {
			return nil, fmt.Errorf("failed to create temp known_hosts file: %s", err)
		}
		defer tf.Close()
		defer os.RemoveAll(tf.Name())

		// we mark this as a CA as well, but the host key fallback will still
		// use it as a direct match if the remote host doesn't return a
		// certificate.
		if _, err := tf.WriteString(fmt.Sprintf("@cert-authority %s %s\n", opts.host, opts.hostKey)); err != nil {
			return nil, fmt.Errorf("failed to write temp known_hosts file: %s", err)
		}
		tf.Sync()

		hkCallback, err = knownhosts.New(tf.Name())
		if err != nil {
			return nil, err
		}
	}

	conf := &ssh.ClientConfig{
		HostKeyCallback: hkCallback,
		User:            opts.user,
	}

	if opts.privateKey != "" {
		if opts.certificate != "" {
			log.Println("using client certificate for authentication")

			certSigner, err := signCertWithPrivateKey(opts.privateKey, opts.certificate)
			if err != nil {
				return nil, err
			}
			conf.Auth = append(conf.Auth, certSigner)
		} else {
			log.Println("using private key for authentication")

			pubKeyAuth, err := readPrivateKey(opts.privateKey)
			if err != nil {
				return nil, err
			}
			conf.Auth = append(conf.Auth, pubKeyAuth)
		}
	}

	if opts.password != "" {
		conf.Auth = append(conf.Auth, ssh.Password(opts.password))
		conf.Auth = append(conf.Auth, ssh.KeyboardInteractive(
			PasswordKeyboardInteractive(opts.password)))
	}

	if opts.sshAgent != nil {
		conf.Auth = append(conf.Auth, opts.sshAgent.Auth())
	}

	return conf, nil
}

// Create a Cert Signer and return ssh.AuthMethod
func signCertWithPrivateKey(pk string, certificate string) (ssh.AuthMethod, error) {
	rawPk, err := ssh.ParseRawPrivateKey([]byte(pk))
	if err != nil {
		return nil, fmt.Errorf("failed to parse private key %q: %s", pk, err)
	}

	pcert, _, _, _, err := ssh.ParseAuthorizedKey([]byte(certificate))
	if err != nil {
		return nil, fmt.Errorf("failed to parse certificate %q: %s", certificate, err)
	}

	usigner, err := ssh.NewSignerFromKey(rawPk)
	if err != nil {
		return nil, fmt.Errorf("failed to create signer from raw private key %q: %s", rawPk, err)
	}

	ucertSigner, err := ssh.NewCertSigner(pcert.(*ssh.Certificate), usigner)
	if err != nil {
		return nil, fmt.Errorf("failed to create cert signer %q: %s", usigner, err)
	}

	return ssh.PublicKeys(ucertSigner), nil
}

func readPrivateKey(pk string) (ssh.AuthMethod, error) {
	// We parse the private key on our own first so that we can
	// show a nicer error if the private key has a password.
	block, _ := pem.Decode([]byte(pk))
	if block == nil {
		return nil, errors.New("Failed to read ssh private key: no key found")
	}
	if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
		return nil, errors.New(
			"Failed to read ssh private key: password protected keys are\n" +
				"not supported. Please decrypt the key prior to use.")
	}

	signer, err := ssh.ParsePrivateKey([]byte(pk))
	if err != nil {
		return nil, fmt.Errorf("Failed to parse ssh private key: %s", err)
	}

	return ssh.PublicKeys(signer), nil
}

func connectToAgent(connInfo *connectionInfo) (*sshAgent, error) {
	if !connInfo.Agent {
		// No agent configured
		return nil, nil
	}

	agent, conn, err := sshagent.New()
	if err != nil {
		return nil, err
	}

	// connection close is handled over in Communicator
	return &sshAgent{
		agent: agent,
		conn:  conn,
		id:    connInfo.AgentIdentity,
	}, nil

}

// A tiny wrapper around an agent.Agent to expose the ability to close its
// associated connection on request.
type sshAgent struct {
	agent agent.Agent
	conn  net.Conn
	id    string
}

func (a *sshAgent) Close() error {
	if a.conn == nil {
		return nil
	}

	return a.conn.Close()
}

// make an attempt to either read the identity file or find a corresponding
// public key file using the typical openssh naming convention.
// This returns the public key in wire format, or nil when a key is not found.
func findIDPublicKey(id string) []byte {
	for _, d := range idKeyData(id) {
		signer, err := ssh.ParsePrivateKey(d)
		if err == nil {
			log.Println("[DEBUG] parsed id private key")
			pk := signer.PublicKey()
			return pk.Marshal()
		}

		// try it as a publicKey
		pk, err := ssh.ParsePublicKey(d)
		if err == nil {
			log.Println("[DEBUG] parsed id public key")
			return pk.Marshal()
		}

		// finally try it as an authorized key
		pk, _, _, _, err = ssh.ParseAuthorizedKey(d)
		if err == nil {
			log.Println("[DEBUG] parsed id authorized key")
			return pk.Marshal()
		}
	}

	return nil
}

// Try to read an id file using the id as the file path. Also read the .pub
// file if it exists, as the id file may be encrypted. Return only the file
// data read. We don't need to know what data came from which path, as we will
// try parsing each as a private key, a public key and an authorized key
// regardless.
func idKeyData(id string) [][]byte {
	idPath, err := filepath.Abs(id)
	if err != nil {
		return nil
	}

	var fileData [][]byte

	paths := []string{idPath}

	if !strings.HasSuffix(idPath, ".pub") {
		paths = append(paths, idPath+".pub")
	}

	for _, p := range paths {
		d, err := ioutil.ReadFile(p)
		if err != nil {
			log.Printf("[DEBUG] error reading %q: %s", p, err)
			continue
		}
		log.Printf("[DEBUG] found identity data at %q", p)
		fileData = append(fileData, d)
	}

	return fileData
}

// sortSigners moves a signer with an agent comment field matching the
// agent_identity to the head of the list when attempting authentication. This
// helps when there are more keys loaded in an agent than the host will allow
// attempts.
func (s *sshAgent) sortSigners(signers []ssh.Signer) {
	if s.id == "" || len(signers) < 2 {
		return
	}

	// if we can locate the public key, either by extracting it from the id or
	// locating the .pub file, then we can more easily determine an exact match
	idPk := findIDPublicKey(s.id)

	// if we have a signer with a connect field that matches the id, send that
	// first, otherwise put close matches at the front of the list.
	head := 0
	for i := range signers {
		pk := signers[i].PublicKey()
		k, ok := pk.(*agent.Key)
		if !ok {
			continue
		}

		// check for an exact match first
		if bytes.Equal(pk.Marshal(), idPk) || s.id == k.Comment {
			signers[0], signers[i] = signers[i], signers[0]
			break
		}

		// no exact match yet, move it to the front if it's close. The agent
		// may have loaded as a full filepath, while the config refers to it by
		// filename only.
		if strings.HasSuffix(k.Comment, s.id) {
			signers[head], signers[i] = signers[i], signers[head]
			head++
			continue
		}
	}
}

func (s *sshAgent) Signers() ([]ssh.Signer, error) {
	signers, err := s.agent.Signers()
	if err != nil {
		return nil, err
	}

	s.sortSigners(signers)
	return signers, nil
}

func (a *sshAgent) Auth() ssh.AuthMethod {
	return ssh.PublicKeysCallback(a.Signers)
}

func (a *sshAgent) ForwardToAgent(client *ssh.Client) error {
	return agent.ForwardToAgent(client, a.agent)
}
