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

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>

#include "usb_bouncer/util.h"
#include "usb_bouncer/util_internal.h"

namespace usb_bouncer {

namespace {

constexpr char kSubdirName[] = "subdir";
constexpr char kSysFSAuthorized[] = "authorized";
constexpr char kSysFSAuthorizedDefault[] = "authorized_default";
constexpr char kSysFSEnabled[] = "1";
constexpr char kSysFSDisabled[] = "0";

bool CreateDisabledFlag(const base::FilePath& flag) {
  if (!base::WriteFile(flag, kSysFSDisabled, sizeof(kSysFSDisabled) - 1)) {
    LOG(ERROR) << "WriteFile('" << flag.value() << "', ...) failed.";
    return false;
  }
  return true;
}

bool CreateDeviceNode(const base::FilePath& dir) {
  if (!base::CreateDirectory(dir)) {
    LOG(ERROR) << "CreateDirectory('" << dir.value() << "') failed.";
    return false;
  }

  return CreateDisabledFlag(dir.Append(kSysFSAuthorized)) &&
         CreateDisabledFlag(dir.Append(kSysFSAuthorizedDefault));
}

bool CheckEnabledFlag(const base::FilePath& flag) {
  std::string flag_content;
  if (!base::ReadFileToString(flag, &flag_content)) {
    LOG(ERROR) << "ReadFileToString('" << flag.value() << "', ...) failed.";
    return false;
  }
  return flag_content == kSysFSEnabled;
}

bool CheckDeviceNodeAuthorized(const base::FilePath& dir) {
  return CheckEnabledFlag(dir.Append(kSysFSAuthorized)) &&
         CheckEnabledFlag(dir.Append(kSysFSAuthorizedDefault));
}

// Mock for testing ForkAndWaitIfDoesNotExist(...). It sets the |taken| to true,
// and always returns 0. If |to_create| isn't empty, it creates a directory at
// that path to make it possible to test the case the path is created after the
// fork.
int ForkMock(bool* taken, const base::FilePath& to_create) {
  *taken = true;

  if (!to_create.empty()) {
    base::CreateDirectory(to_create);
  }

  // Always take the child path, because the parent path exits.
  return 0;
}

}  // namespace

TEST(UtilTest, IncludeRuleAtLockscreen) {
  EXPECT_FALSE(IncludeRuleAtLockscreen(""));

  const std::string blocked_device =
      "allow id 0781:5588 serial \"12345678BF05\" name \"USB Extreme Pro\" "
      "hash \"9hMkYEMPjuNegGmzLIKwUp2MPctSL0tCWk7ruWGuOzc=\" with-interface "
      "08:06:50 with-connect-type \"unknown\"";
  EXPECT_FALSE(IncludeRuleAtLockscreen(blocked_device))
      << "Failed to filter: " << blocked_device;

  const std::string allowed_device =
      "allow id 0bda:8153 serial \"000001000000\" name \"USB 10/100/1000 LAN\" "
      "hash \"dljXy8thtljhoJo+O+hfhSlp1J89rz0Z4404iqKzakI=\" with-interface "
      "{ ff:ff:00 02:06:00 0a:00:00 0a:00:00 }";
  EXPECT_TRUE(IncludeRuleAtLockscreen(allowed_device))
      << "Failed to allow:" << allowed_device;
}

TEST(UtilTest, AuthorizeAll_Success) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  ASSERT_TRUE(AuthorizeAll(temp_dir_.GetPath().value()));

  const base::FilePath subdir = temp_dir_.GetPath().Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(subdir))
      << "CreateDeviceNode('" << subdir.value() << "') failed.";
  const base::FilePath deepdir =
      temp_dir_.GetPath().Append(kSubdirName).Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(deepdir))
      << "CreateDeviceNode('" << deepdir.value() << "') failed.";

  EXPECT_TRUE(AuthorizeAll(temp_dir_.GetPath().value()));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(subdir));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(deepdir));
}

TEST(UtilTest, AuthorizeAll_Failure) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);

  const base::FilePath subdir = temp_dir_.GetPath().Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(subdir))
      << "CreateDeviceNode('" << subdir.value() << "') failed.";
  const base::FilePath deepdir =
      temp_dir_.GetPath().Append(kSubdirName).Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(deepdir))
      << "CreateDeviceNode('" << deepdir.value() << "') failed.";

  chmod(subdir.Append(kSysFSAuthorizedDefault).value().c_str(), 0000);

  EXPECT_FALSE(AuthorizeAll(temp_dir_.GetPath().value()));
  EXPECT_FALSE(CheckDeviceNodeAuthorized(subdir));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(deepdir));
}

TEST(UtilTest, ForkAndWaitIfPathUnavailable_PathExists) {
  base::FilePath empty_path;
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);

  bool fork_taken = false;
  EXPECT_TRUE(ForkAndWaitIfDoesNotExist(
      temp_dir_.GetPath(), base::TimeDelta::FromSeconds(0),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), empty_path)));
  EXPECT_FALSE(fork_taken);
}

TEST(UtilTest, ForkAndWaitIfPathUnavailable_PathDoesntExistTimeout) {
  base::FilePath empty_path;
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  base::FilePath sub_dir_ = temp_dir_.GetPath().Append("DoesNotExist");
  LOG(INFO) << "PATH: " << sub_dir_.value();

  bool fork_taken = false;
  EXPECT_FALSE(ForkAndWaitIfDoesNotExist(
      sub_dir_, base::TimeDelta::FromSeconds(0),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), empty_path)));
  EXPECT_TRUE(fork_taken);
}

TEST(UtilTest, ForkAndWaitIfPathUnavailable_PathDoesntExistSucceed) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  base::FilePath sub_dir_ = temp_dir_.GetPath().Append("ExistsAfterFork");

  bool fork_taken = false;
  EXPECT_TRUE(ForkAndWaitIfDoesNotExist(
      sub_dir_, base::TimeDelta::FromSeconds(1),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), sub_dir_)));
  EXPECT_TRUE(fork_taken);
}

TEST(UtilTest, GetRuleFromString_Success) {
  EXPECT_TRUE(GetRuleFromString("allow id 0000:0000"));
}

TEST(UtilTest, GetRuleFromString_Failure) {
  EXPECT_FALSE(GetRuleFromString("aaff44"));
}

TEST(UtilTest, GetClassFromRule_EmptyInterfaces) {
  auto rule = GetRuleFromString("allow id 0000:0000");
  ASSERT_TRUE(rule);
  ASSERT_TRUE(rule.attributeWithInterface().empty());
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kOther);
}

TEST(UtilTest, GetClassFromRule_SingleInterface) {
  auto rule = GetRuleFromString("allow with-interface 03:00:01");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 1);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kHID);
}

TEST(UtilTest, GetClassFromRule_MatchingInterfaces) {
  auto rule = GetRuleFromString("allow with-interface { 03:00:00 03:00:01 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 2);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kHID);
}

TEST(UtilTest, GetClassFromRule_DifferentInterfaces) {
  auto rule = GetRuleFromString("allow with-interface { 03:00:00 09:00:00 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 2);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kOther);
}

TEST(UtilTest, GetClassFromRule_AV) {
  auto rule =
      GetRuleFromString("allow with-interface { 01:00:00 0E:00:00 10:00:00 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 3);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kAV);
}

}  // namespace usb_bouncer
