// Copyright 2017 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.

// Tests for ssh client multi-auth
//
// These tests run a simple go ssh client against OpenSSH server
// over unix domain sockets. The tests use multiple combinations
// of password, keyboard-interactive and publickey authentication
// methods.
//
// A wrapper library for making sshd PAM authentication use test
// passwords is required in ./sshd_test_pw.so. If the library does
// not exist these tests will be skipped. See compile instructions
// (for linux) in file ./sshd_test_pw.c.

//go:build linux
// +build linux

package test

import (
	"fmt"
	"strings"
	"testing"

	"golang.org/x/crypto/ssh"
)

// test cases
type multiAuthTestCase struct {
	authMethods         []string
	expectedPasswordCbs int
	expectedKbdIntCbs   int
}

// test context
type multiAuthTestCtx struct {
	password       string
	numPasswordCbs int
	numKbdIntCbs   int
}

// create test context
func newMultiAuthTestCtx(t *testing.T) *multiAuthTestCtx {
	password, err := randomPassword()
	if err != nil {
		t.Fatalf("Failed to generate random test password: %s", err.Error())
	}

	return &multiAuthTestCtx{
		password: password,
	}
}

// password callback
func (ctx *multiAuthTestCtx) passwordCb() (secret string, err error) {
	ctx.numPasswordCbs++
	return ctx.password, nil
}

// keyboard-interactive callback
func (ctx *multiAuthTestCtx) kbdIntCb(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
	if len(questions) == 0 {
		return nil, nil
	}

	ctx.numKbdIntCbs++
	if len(questions) == 1 {
		return []string{ctx.password}, nil
	}

	return nil, fmt.Errorf("unsupported keyboard-interactive flow")
}

// TestMultiAuth runs several subtests for different combinations of password, keyboard-interactive and publickey authentication methods
func TestMultiAuth(t *testing.T) {
	testCases := []multiAuthTestCase{
		// Test password,publickey authentication, assert that password callback is called 1 time
		multiAuthTestCase{
			authMethods:         []string{"password", "publickey"},
			expectedPasswordCbs: 1,
		},
		// Test keyboard-interactive,publickey authentication, assert that keyboard-interactive callback is called 1 time
		multiAuthTestCase{
			authMethods:       []string{"keyboard-interactive", "publickey"},
			expectedKbdIntCbs: 1,
		},
		// Test publickey,password authentication, assert that password callback is called 1 time
		multiAuthTestCase{
			authMethods:         []string{"publickey", "password"},
			expectedPasswordCbs: 1,
		},
		// Test publickey,keyboard-interactive authentication, assert that keyboard-interactive callback is called 1 time
		multiAuthTestCase{
			authMethods:       []string{"publickey", "keyboard-interactive"},
			expectedKbdIntCbs: 1,
		},
		// Test password,password authentication, assert that password callback is called 2 times
		multiAuthTestCase{
			authMethods:         []string{"password", "password"},
			expectedPasswordCbs: 2,
		},
	}

	for _, testCase := range testCases {
		t.Run(strings.Join(testCase.authMethods, ","), func(t *testing.T) {
			ctx := newMultiAuthTestCtx(t)

			server := newServerForConfig(t, "MultiAuth", map[string]string{"AuthMethods": strings.Join(testCase.authMethods, ",")})
			defer server.Shutdown()

			clientConfig := clientConfig()
			server.setTestPassword(clientConfig.User, ctx.password)

			publicKeyAuthMethod := clientConfig.Auth[0]
			clientConfig.Auth = nil
			for _, authMethod := range testCase.authMethods {
				switch authMethod {
				case "publickey":
					clientConfig.Auth = append(clientConfig.Auth, publicKeyAuthMethod)
				case "password":
					clientConfig.Auth = append(clientConfig.Auth,
						ssh.RetryableAuthMethod(ssh.PasswordCallback(ctx.passwordCb), 5))
				case "keyboard-interactive":
					clientConfig.Auth = append(clientConfig.Auth,
						ssh.RetryableAuthMethod(ssh.KeyboardInteractive(ctx.kbdIntCb), 5))
				default:
					t.Fatalf("Unknown authentication method %s", authMethod)
				}
			}

			conn := server.Dial(clientConfig)
			defer conn.Close()

			if ctx.numPasswordCbs != testCase.expectedPasswordCbs {
				t.Fatalf("passwordCallback was called %d times, expected %d times", ctx.numPasswordCbs, testCase.expectedPasswordCbs)
			}

			if ctx.numKbdIntCbs != testCase.expectedKbdIntCbs {
				t.Fatalf("keyboardInteractiveCallback was called %d times, expected %d times", ctx.numKbdIntCbs, testCase.expectedKbdIntCbs)
			}
		})
	}
}
