// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build go1.16 && (linux || darwin)
// +build go1.16
// +build linux darwin

package remote

import (
	"context"
	"fmt"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/build/buildlet"
	"golang.org/x/crypto/ssh"
	"golang.org/x/net/nettest"
)

func TestSignPublicSSHKey(t *testing.T) {
	signer, err := ssh.ParsePrivateKey([]byte(devCertCAPrivate))
	if err != nil {
		t.Fatalf("ssh.ParsePrivateKey() = %s", err)
	}
	ownerID := "accounts.google.com:userIDvalue"
	sessionID := "user-maria-linux-amd64-12"
	gotPubKey, err := SignPublicSSHKey(context.Background(), signer, []byte(devCertClientPublic), sessionID, ownerID, time.Minute)
	if err != nil {
		t.Fatalf("SignPublicSSHKey(...) = _, %s; want no error", err)
	}
	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(gotPubKey)
	if err != nil {
		t.Fatalf("ssh.ParseAuthorizedKey(...) = %s; want no error", err)
	}
	certChecker := &ssh.CertChecker{}
	wantPrinciple := fmt.Sprintf("%s@farmer.golang.org", sessionID)
	pubKeyCert := pubKey.(*ssh.Certificate)
	if err := certChecker.CheckCert(wantPrinciple, pubKeyCert); err != nil {
		t.Fatalf("certChecker.CheckCert(%s, %+v) = %s", wantPrinciple, pubKeyCert, err)
	}
	if diff := cmp.Diff(pubKeyCert.SignatureKey.Marshal(), signer.PublicKey().Marshal()); diff != "" {
		t.Fatalf("Public Keys mismatch (-want +got):\n%s", diff)
	}
}

func TestHandleCertificateAuthFunc(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	addr, sp, s := setupSSHServer(t, ctx)
	defer s.Close()

	ownerID := "accounts.google.com:userIDvalue"
	sessionID := sp.AddSession(ownerID, "maria", "linux-amd64", "xyz", &buildlet.FakeClient{})
	certSigner := parsePrivateKey(t, []byte(devCertCAPrivate))
	clientPubKey, err := SignPublicSSHKey(ctx, certSigner, []byte(devCertClientPublic), sessionID, ownerID, time.Minute)
	if err != nil {
		t.Fatalf("SignPublicSSHKey(...) = _, %s; want no error", err)
	}
	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(clientPubKey)
	if err != nil {
		t.Fatalf("ParsePublicKey(...) = _, %s; want no error", err)
	}
	cert := pubKey.(*ssh.Certificate)
	clientCertSigner := parsePrivateKey(t, []byte(devCertClientPrivate))
	clientSigner, err := ssh.NewCertSigner(cert, clientCertSigner)
	if err != nil {
		t.Fatalf("NewCertSigner(...) = _, %s; want no error", err)
	}
	clientConfig := &ssh.ClientConfig{
		User: sessionID,
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(clientSigner),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         5 * time.Second,
	}
	client, err := ssh.Dial("tcp", addr, clientConfig)
	if err != nil {
		t.Fatalf("Dial(...) = _, %s; want no error", err)
	}
	client.Close()
}

func TestHandleCertificateAuthFuncErrors(t *testing.T) {
	t.Run("no certificate", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		addr, sp, s := setupSSHServer(t, ctx)
		defer s.Close()

		ownerID := "accounts.google.com:userIDvalue"
		sessionID := sp.AddSession(ownerID, "maria", "linux-amd64", "xyz", &buildlet.FakeClient{})
		clientSigner := parsePrivateKey(t, []byte(devCertClientPrivate))
		clientConfig := &ssh.ClientConfig{
			User: sessionID,
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(clientSigner),
			},
			HostKeyCallback: ssh.InsecureIgnoreHostKey(),
			Timeout:         5 * time.Second,
		}
		_, err := ssh.Dial("tcp", addr, clientConfig)
		if err == nil {
			t.Fatal("Dial(...) = client, nil; want error")
		}
	})

	t.Run("wrong certificate signer", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		addr, sp, s := setupSSHServer(t, ctx)
		defer s.Close()

		ownerID := "accounts.google.com:userIDvalue"
		sessionID := sp.AddSession(ownerID, "maria", "linux-amd64", "xyz", &buildlet.FakeClient{})
		certSigner := parsePrivateKey(t, []byte(devCertAlternateClientPrivate))
		clientPubKey, err := SignPublicSSHKey(ctx, certSigner, []byte(devCertClientPublic), sessionID, ownerID, time.Minute)
		if err != nil {
			t.Fatalf("SignPublicSSHKey(...) = _, %s; want no error", err)
		}
		pubKey, _, _, _, err := ssh.ParseAuthorizedKey(clientPubKey)
		if err != nil {
			t.Fatalf("ParsePublicKey(...) = _, %s; want no error", err)
		}
		cert := pubKey.(*ssh.Certificate)
		clientCertSigner := parsePrivateKey(t, []byte(devCertClientPrivate))
		clientSigner, err := ssh.NewCertSigner(cert, clientCertSigner)
		if err != nil {
			t.Fatalf("NewCertSigner(...) = _, %s; want no error", err)
		}
		clientConfig := &ssh.ClientConfig{
			User: sessionID,
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(clientSigner),
			},
			HostKeyCallback: ssh.InsecureIgnoreHostKey(),
			Timeout:         5 * time.Second,
		}
		_, err = ssh.Dial("tcp", addr, clientConfig)
		if err == nil {
			t.Fatalf("Dial(...) = _, %s; want no error", err)
		}
	})

	t.Run("wrong user", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		addr, sp, s := setupSSHServer(t, ctx)
		defer s.Close()

		ownerID := "accounts.google.com:userIDvalue"
		sessionID := sp.AddSession(ownerID, "maria", "linux-amd64", "xyz", &buildlet.FakeClient{})
		certSigner := parsePrivateKey(t, []byte(devCertCAPrivate))
		clientPubKey, err := SignPublicSSHKey(ctx, certSigner, []byte(devCertClientPublic), sessionID, ownerID, time.Minute)
		if err != nil {
			t.Fatalf("SignPublicSSHKey(...) = _, %s; want no error", err)
		}
		pubKey, _, _, _, err := ssh.ParseAuthorizedKey(clientPubKey)
		if err != nil {
			t.Fatalf("ParsePublicKey(...) = _, %s; want no error", err)
		}
		cert := pubKey.(*ssh.Certificate)
		clientCertSigner := parsePrivateKey(t, []byte(devCertClientPrivate))
		clientSigner, err := ssh.NewCertSigner(cert, clientCertSigner)
		if err != nil {
			t.Fatalf("NewCertSigner(...) = _, %s; want no error", err)
		}
		clientConfig := &ssh.ClientConfig{
			User: sessionID + "_i_do_not_exist",
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(clientSigner),
			},
			HostKeyCallback: ssh.InsecureIgnoreHostKey(),
			Timeout:         5 * time.Second,
		}
		_, err = ssh.Dial("tcp", addr, clientConfig)
		if err == nil {
			t.Fatal("Dial(...) = _, nil; want error")
		}
	})

	t.Run("wrong principle", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		addr, sp, s := setupSSHServer(t, ctx)
		defer s.Close()

		ownerID := "accounts.google.com:userIDvalue"
		sessionID := sp.AddSession(ownerID, "maria", "linux-amd64", "xyz", &buildlet.FakeClient{})
		certSigner := parsePrivateKey(t, []byte(devCertCAPrivate))
		clientPubKey, err := SignPublicSSHKey(ctx, certSigner, []byte(devCertClientPublic), sessionID+"WRONG", ownerID, time.Minute)
		if err != nil {
			t.Fatalf("SignPublicSSHKey(...) = _, %s; want no error", err)
		}
		pubKey, _, _, _, err := ssh.ParseAuthorizedKey(clientPubKey)
		if err != nil {
			t.Fatalf("ParsePublicKey(...) = _, %s; want no error", err)
		}
		cert := pubKey.(*ssh.Certificate)
		clientCertSigner := parsePrivateKey(t, []byte(devCertClientPrivate))
		clientSigner, err := ssh.NewCertSigner(cert, clientCertSigner)
		if err != nil {
			t.Fatalf("NewCertSigner(...) = _, %s; want no error", err)
		}
		clientConfig := &ssh.ClientConfig{
			User: sessionID,
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(clientSigner),
			},
			HostKeyCallback: ssh.InsecureIgnoreHostKey(),
			Timeout:         5 * time.Second,
		}
		_, err = ssh.Dial("tcp", addr, clientConfig)
		if err == nil {
			t.Fatal("Dial(...) = _, nil; want error")
		}
	})

}

func setupSSHServer(t *testing.T, ctx context.Context) (addr string, sp *SessionPool, s *SSHServer) {
	sp = NewSessionPool(ctx)
	l, err := nettest.NewLocalListener("tcp")
	if err != nil {
		t.Fatalf("nettest.NewLocalListener(tcp) = _, %s; want no error", err)
	}
	addr = l.Addr().String()
	rbs := &Buildlets{
		M: map[string]*Buildlet{},
	}
	s, err = NewSSHServer(addr, []byte(devCertAlternateClientPrivate), []byte(devCertCAPublic), []byte(devCertCAPrivate), sp, rbs)
	if err != nil {
		t.Fatalf("NewSSHServer(...) = %s; want no error", err)
	}
	go s.serve(l)
	if err != nil {
		t.Fatalf("server.serve(l) = %s; want no error", err)
	}
	return
}

func parsePrivateKey(t *testing.T, pemEncoded []byte) ssh.Signer {
	cert, err := ssh.ParsePrivateKey(pemEncoded)
	if err != nil {
		t.Fatalf("ssh.ParsePrivateKey() = _, %s; want no error", err)
	}
	return cert
}

const (
	// devCertCAPrivate is a private SSH CA certificate to be used for development.
	devCertCAPrivate = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCVd2FJ3Db/oV53iRDt1RLscTn41hYXbunuCWIlXze2WAAAAJhjy3ePY8t3
jwAAAAtzc2gtZWQyNTUxOQAAACCVd2FJ3Db/oV53iRDt1RLscTn41hYXbunuCWIlXze2WA
AAAEALuUJMb/rEaFNa+vn5RejeoBiiViyda7djgEvMnQ8fRJV3YUncNv+hXneJEO3VEuxx
OfjWFhdu6e4JYiVfN7ZYAAAAE3Rlc3R1c2VyQGdvbGFuZy5vcmcBAg==
-----END OPENSSH PRIVATE KEY-----`

	// devCertCAPublic is a public SSH CA certificate to be used for development.
	devCertCAPublic = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJV3YUncNv+hXneJEO3VEuxxOfjWFhdu6e4JYiVfN7ZY testuser@golang.org`

	// devCertClientPrivate is a private SSH certificate to be used for development.
	devCertClientPrivate = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBxCM6ADdHnjTIHG/IpMa3z32CLwtu3BDUR3k2NNbI3owAAAKDFZ7xtxWe8
bQAAAAtzc2gtZWQyNTUxOQAAACBxCM6ADdHnjTIHG/IpMa3z32CLwtu3BDUR3k2NNbI3ow
AAAECidrOyYbTlYxyBSPP7W/UHk3Si2dgWSfkT+eEIETcvqHEIzoAN0eeNMgcb8ikxrfPf
YIvC27cENRHeTY01sjejAAAAFnRlc3RfY2xpZW50QGdvbGFuZy5vcmcBAgMEBQYH
-----END OPENSSH PRIVATE KEY-----`

	// devCertClientPublic is a public SSH certificate to be used for development.
	devCertClientPublic = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHEIzoAN0eeNMgcb8ikxrfPfYIvC27cENRHeTY01sjej test_client@golang.org`

	// devCertAlternateClientPrivate is a private SSH certificate to be used for development.
	devCertAlternateClientPrivate = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDOj8K2lbCSv+LojNcrUf0XH1vqknuEZBkAceiBHuNuEQAAAKDYNRtZ2DUb
WQAAAAtzc2gtZWQyNTUxOQAAACDOj8K2lbCSv+LojNcrUf0XH1vqknuEZBkAceiBHuNuEQ
AAAEDS4G3tQt5S4v7CD+DVyT/mwOKgIScIgFOpFt/EsCXL9M6PwraVsJK/4uiM1ytR/Rcf
W+qSe4RkGQBx6IEe424RAAAAF3Rlc3RfZGlzY2FyZEBnb2xhbmcub3JnAQIDBAUG
-----END OPENSSH PRIVATE KEY-----`

	// devCertAlternateClientPublic is a public SSH to be used for development.
	devCertAlternateClientPublic = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6PwraVsJK/4uiM1ytR/RcfW+qSe4RkGQBx6IEe424R test_discard@golang.org`
)
