// Copyright 2020 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 "system-proxy/system_proxy_adaptor.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <iterator>
#include <list>
#include <map>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback_helpers.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/stringprintf.h>
#include <base/strings/utf_string_conversions.h>
#include <base/task/single_thread_task_executor.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <brillo/dbus/dbus_object.h>
#include <brillo/message_loops/base_message_loop.h>
#include <dbus/object_path.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/mock_object_proxy.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/kerberos/dbus-constants.h>
#include <dbus/system_proxy/dbus-constants.h>
#include <libpasswordprovider/fake_password_provider.h>
#include <libpasswordprovider/password_provider_test_utils.h>

#include "bindings/worker_common.pb.h"
#include "system-proxy/kerberos_client.h"
#include "system-proxy/net/ntlm/ntlm_test_data.h"
#include "system_proxy/proto_bindings/system_proxy_service.pb.h"
#include "system-proxy/protobuf_util.h"
#include "system-proxy/sandboxed_worker.h"

using testing::_;
using testing::Return;

namespace system_proxy {
namespace {
const char kUser[] = "proxy_user";
const char kPassword[] = "proxy_password";
const char kPrincipalName[] = "user@TEST";
const char kLocalProxyHostPort[] = "local.proxy.url:3128";
const char kObjectPath[] = "/object/path";

// Stub completion callback for RegisterAsync().
void DoNothing(bool /* unused */) {}

}  // namespace

class FakeSandboxedWorker : public SandboxedWorker {
 public:
  explicit FakeSandboxedWorker(base::WeakPtr<SystemProxyAdaptor> adaptor)
      : SandboxedWorker(adaptor) {}
  FakeSandboxedWorker(const FakeSandboxedWorker&) = delete;
  FakeSandboxedWorker& operator=(const FakeSandboxedWorker&) = delete;
  ~FakeSandboxedWorker() override = default;

  bool Start() override { return is_running_ = true; }
  bool Stop() override {
    is_running_ = false;
    return true;
  }
  bool IsRunning() override { return is_running_; }

  std::string local_proxy_host_and_port() override {
    return kLocalProxyHostPort;
  }

 private:
  bool is_running_;
};

class FakeSystemProxyAdaptor : public SystemProxyAdaptor {
 public:
  FakeSystemProxyAdaptor(
      std::unique_ptr<brillo::dbus_utils::DBusObject> dbus_object)
      : SystemProxyAdaptor(std::move(dbus_object)), weak_ptr_factory_(this) {
    password_provider_ =
        std::make_unique<password_provider::FakePasswordProvider>();
  }
  FakeSystemProxyAdaptor(const FakeSystemProxyAdaptor&) = delete;
  FakeSystemProxyAdaptor& operator=(const FakeSystemProxyAdaptor&) = delete;
  ~FakeSystemProxyAdaptor() override = default;

  password_provider::PasswordProviderInterface* GetPasswordProvider() override {
    return password_provider_.get();
  }

 protected:
  std::unique_ptr<SandboxedWorker> CreateWorker() override {
    ++create_worker_count_;
    return std::make_unique<FakeSandboxedWorker>(
        weak_ptr_factory_.GetWeakPtr());
  }
  void ConnectNamespace(bool user_traffic) override {
    OnNamespaceConnected(GetWorker(user_traffic), user_traffic);
  }

 private:
  FRIEND_TEST(SystemProxyAdaptorTest, KerberosEnabled);
  FRIEND_TEST(SystemProxyAdaptorTest, ConnectNamespace);
  FRIEND_TEST(SystemProxyAdaptorTest, ProxyResolutionFilter);
  FRIEND_TEST(SystemProxyAdaptorTest, ProtectionSpaceAuthenticationRequired);
  FRIEND_TEST(SystemProxyAdaptorTest, ProtectionSpaceNoCredentials);
  FRIEND_TEST(SystemProxyAdaptorTest, ClearUserCredentials);
  FRIEND_TEST(SystemProxyAdaptorTest, ClearUserCredentialsRestartService);

  int create_worker_count_ = 0;

  std::unique_ptr<password_provider::PasswordProviderInterface>
      password_provider_;
  base::WeakPtrFactory<FakeSystemProxyAdaptor> weak_ptr_factory_;
};

class SystemProxyAdaptorTest : public ::testing::Test {
 public:
  SystemProxyAdaptorTest() {
    const dbus::ObjectPath object_path(kObjectPath);

    // Mock out D-Bus initialization.
    mock_exported_object_ =
        base::MakeRefCounted<dbus::MockExportedObject>(bus_.get(), object_path);

    EXPECT_CALL(*bus_, GetExportedObject(_))
        .WillRepeatedly(Return(mock_exported_object_.get()));

    EXPECT_CALL(*mock_exported_object_, ExportMethod(_, _, _, _))
        .Times(testing::AnyNumber());

    mock_kerberos_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
        bus_.get(), kerberos::kKerberosServiceName,
        dbus::ObjectPath(kerberos::kKerberosServicePath));
    EXPECT_CALL(*bus_, GetObjectProxy(kerberos::kKerberosServiceName, _))
        .WillRepeatedly(Return(mock_kerberos_proxy_.get()));

    adaptor_.reset(new FakeSystemProxyAdaptor(
        std::make_unique<brillo::dbus_utils::DBusObject>(nullptr, bus_,
                                                         object_path)));
    adaptor_->RegisterAsync(base::BindRepeating(&DoNothing));
    mock_patchpanel_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
        bus_.get(), patchpanel::kPatchPanelServiceName,
        dbus::ObjectPath(patchpanel::kPatchPanelServicePath));
    brillo_loop_.SetAsCurrent();
  }
  SystemProxyAdaptorTest(const SystemProxyAdaptorTest&) = delete;
  SystemProxyAdaptorTest& operator=(const SystemProxyAdaptorTest&) = delete;
  ~SystemProxyAdaptorTest() override = default;

  void AddCredentialsToAuthCache(
      const worker::ProtectionSpace& protection_space,
      const std::string& username,
      const std::string& password) {
    Credentials credentials;
    credentials.set_username(username);
    credentials.set_password(password);
    mock_auth_cache_[protection_space.SerializeAsString()] = credentials;
  }

  void OnWorkerActive(dbus::Signal* signal) {
    EXPECT_EQ(signal->GetInterface(), "org.chromium.SystemProxy");
    EXPECT_EQ(signal->GetMember(), "WorkerActive");
    active_worker_signal_called_ = true;

    dbus::MessageReader signal_reader(signal);
    system_proxy::WorkerActiveSignalDetails details;
    EXPECT_TRUE(signal_reader.PopArrayOfBytesAsProto(&details));
    EXPECT_EQ(kLocalProxyHostPort, details.local_proxy_url());
  }

  void OnAuthenticationRequired(dbus::Signal* signal) {
    EXPECT_EQ(signal->GetInterface(), "org.chromium.SystemProxy");
    EXPECT_EQ(signal->GetMember(), "AuthenticationRequired");

    dbus::MessageReader signal_reader(signal);
    system_proxy::AuthenticationRequiredDetails details;
    EXPECT_TRUE(signal_reader.PopArrayOfBytesAsProto(&details));

    Credentials credentials;

    auto it = mock_auth_cache_.find(
        details.proxy_protection_space().SerializeAsString());

    if (it != mock_auth_cache_.end()) {
      credentials = it->second;
    } else {
      credentials.set_username("");
      credentials.set_password("");
    }

    SetAuthenticationDetailsRequest request;
    *request.mutable_credentials() = credentials;
    *request.mutable_protection_space() = details.proxy_protection_space();
    request.set_traffic_type(TrafficOrigin::SYSTEM);

    std::vector<uint8_t> proto_blob(request.ByteSizeLong());
    request.SerializeToArray(proto_blob.data(), proto_blob.size());

    adaptor_->SetAuthenticationDetails(proto_blob);
    ASSERT_TRUE(brillo_loop_.RunOnce(/*may_block=*/false));
  }

 protected:
  bool active_worker_signal_called_ = false;
  std::map<std::string, Credentials> mock_auth_cache_;
  scoped_refptr<dbus::MockBus> bus_ = new dbus::MockBus(dbus::Bus::Options());
  scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
  // SystemProxyAdaptor instance that creates fake worker processes.
  std::unique_ptr<FakeSystemProxyAdaptor> adaptor_;

  scoped_refptr<dbus::MockObjectProxy> mock_patchpanel_proxy_;
  scoped_refptr<dbus::MockObjectProxy> mock_kerberos_proxy_;

  base::SingleThreadTaskExecutor task_executor_{base::MessagePumpType::IO};
  brillo::BaseMessageLoop brillo_loop_{task_executor_.task_runner()};
};

// Verifies if System-proxy starts the system and user traffic workers and sets
// the credentials for both workers.
TEST_F(SystemProxyAdaptorTest, SetAuthenticationDetails) {
  EXPECT_CALL(*bus_, GetObjectProxy(patchpanel::kPatchPanelServiceName, _))
      .Times(2)
      .WillRepeatedly(Return(mock_patchpanel_proxy_.get()));

  EXPECT_FALSE(adaptor_->system_services_worker_.get());
  SetAuthenticationDetailsRequest request;
  Credentials credentials;
  credentials.set_username(kUser);
  credentials.set_password(kPassword);
  credentials.add_policy_credentials_auth_schemes("basic");
  credentials.add_policy_credentials_auth_schemes("digest");

  *request.mutable_credentials() = credentials;
  request.set_traffic_type(TrafficOrigin::ALL);

  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());

  // First create a worker object.
  adaptor_->SetAuthenticationDetails(proto_blob);
  ASSERT_TRUE(brillo_loop_.RunOnce(/*may_block=*/false));

  ASSERT_TRUE(adaptor_->system_services_worker_.get());
  EXPECT_TRUE(adaptor_->system_services_worker_->IsRunning());
  ASSERT_TRUE(adaptor_->arc_worker_.get());
  EXPECT_TRUE(adaptor_->arc_worker_->IsRunning());

  // Verify that credentials were set for user and system traffic.
  int fds_system[2], fds_user[2];
  EXPECT_TRUE(base::CreateLocalNonBlockingPipe(fds_system));
  base::ScopedFD read_scoped_fd_system(fds_system[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds_system[1]);
  EXPECT_TRUE(base::CreateLocalNonBlockingPipe(fds_user));
  base::ScopedFD read_scoped_fd_user(fds_user[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->arc_worker_->stdin_pipe_.reset(fds_user[1]);

  adaptor_->SetAuthenticationDetails(proto_blob);
  // Process the tasks which send credentials to both workers via communication
  // pipes.
  ASSERT_TRUE(brillo_loop_.RunOnce(/*may_block=*/false));
  ASSERT_TRUE(brillo_loop_.RunOnce(/*may_block=*/false));

  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd_system.get(), &config));
  EXPECT_TRUE(config.has_credentials());
  EXPECT_EQ(config.credentials().username(), kUser);
  EXPECT_EQ(config.credentials().password(), kPassword);

  worker::WorkerConfigs config_user;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd_user.get(), &config_user));
  EXPECT_TRUE(config_user.has_credentials());
  EXPECT_EQ(config_user.credentials().username(), kUser);
  EXPECT_EQ(config_user.credentials().password(), kPassword);
  EXPECT_GT(credentials.policy_credentials_auth_schemes().size(), 0);
  EXPECT_EQ(credentials.policy_credentials_auth_schemes().Get(0), "basic");
  EXPECT_EQ(credentials.policy_credentials_auth_schemes().Get(1), "digest");
}

// Verifies if System-proxy only starts the worker which tunnels system traffic.
TEST_F(SystemProxyAdaptorTest, SetAuthenticationDetailsOnlySystemTraffic) {
  EXPECT_CALL(*bus_, GetObjectProxy(patchpanel::kPatchPanelServiceName, _))
      .WillOnce(Return(mock_patchpanel_proxy_.get()));

  EXPECT_FALSE(adaptor_->system_services_worker_.get());
  SetAuthenticationDetailsRequest request;
  Credentials credentials;
  credentials.set_username(kUser);
  credentials.set_password(kPassword);
  *request.mutable_credentials() = credentials;
  request.set_traffic_type(TrafficOrigin::SYSTEM);

  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());

  adaptor_->SetAuthenticationDetails(proto_blob);
  ASSERT_TRUE(brillo_loop_.RunOnce(/*may_block=*/false));

  ASSERT_TRUE(adaptor_->system_services_worker_.get());
  EXPECT_TRUE(adaptor_->system_services_worker_->IsRunning());
  EXPECT_FALSE(adaptor_->arc_worker_);
}

TEST_F(SystemProxyAdaptorTest, KerberosEnabled) {
  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  ASSERT_TRUE(adaptor_->system_services_worker_.get());

  int fds[2];
  ASSERT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds[1]);

  SetAuthenticationDetailsRequest request;
  request.set_kerberos_enabled(true);
  request.set_active_principal_name(kPrincipalName);
  request.set_traffic_type(TrafficOrigin::SYSTEM);

  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());

  // First create a worker object.
  adaptor_->SetAuthenticationDetails(proto_blob);
  brillo_loop_.RunOnce(false);

  // Expect that the availability of kerberos auth has been sent to the worker.
  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd.get(), &config));
  EXPECT_TRUE(config.has_kerberos_config());
  EXPECT_TRUE(config.kerberos_config().enabled());
  EXPECT_EQ(config.kerberos_config().krb5cc_path(), "/tmp/ccache");
  EXPECT_EQ(config.kerberos_config().krb5conf_path(), "/tmp/krb5.conf");

  // Expect that the availability of kerberos auth has been sent to the kerberos
  // client.
  EXPECT_TRUE(adaptor_->kerberos_client_->kerberos_enabled_);
  EXPECT_EQ(adaptor_->kerberos_client_->principal_name_, kPrincipalName);
}

TEST_F(SystemProxyAdaptorTest, ShutDown) {
  EXPECT_CALL(*bus_, GetObjectProxy(patchpanel::kPatchPanelServiceName, _))
      .Times(2)
      .WillRepeatedly(Return(mock_patchpanel_proxy_.get()));
  adaptor_->CreateWorkerIfNeeded(/*user_traffic=*/false);
  adaptor_->CreateWorkerIfNeeded(/*user_traffic=*/true);
  EXPECT_TRUE(adaptor_->system_services_worker_);
  EXPECT_TRUE(adaptor_->arc_worker_);

  ShutDownRequest request;
  request.set_traffic_type(TrafficOrigin::ALL);
  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());
  adaptor_->ShutDownProcess(proto_blob);

  EXPECT_FALSE(adaptor_->system_services_worker_);
  EXPECT_FALSE(adaptor_->arc_worker_);
}

// Verifies that only the worker that tunnels ARC traffic is shut down.
TEST_F(SystemProxyAdaptorTest, ShutDownArc) {
  EXPECT_CALL(*bus_, GetObjectProxy(patchpanel::kPatchPanelServiceName, _))
      .Times(2)
      .WillRepeatedly(Return(mock_patchpanel_proxy_.get()));
  adaptor_->CreateWorkerIfNeeded(/*user_traffic=*/false);
  adaptor_->CreateWorkerIfNeeded(/*user_traffic=*/true);
  EXPECT_TRUE(adaptor_->system_services_worker_);
  EXPECT_TRUE(adaptor_->arc_worker_);

  ShutDownRequest request;
  request.set_traffic_type(TrafficOrigin::USER);
  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());
  adaptor_->ShutDownProcess(proto_blob);

  EXPECT_TRUE(adaptor_->system_services_worker_);
  EXPECT_FALSE(adaptor_->arc_worker_);
}

TEST_F(SystemProxyAdaptorTest, ConnectNamespace) {
  EXPECT_FALSE(active_worker_signal_called_);
  EXPECT_CALL(*mock_exported_object_, SendSignal(_))
      .WillOnce(Invoke(this, &SystemProxyAdaptorTest::OnWorkerActive));

  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  adaptor_->ConnectNamespace(/* user_traffic= */ false);
  EXPECT_TRUE(active_worker_signal_called_);
}

TEST_F(SystemProxyAdaptorTest, ProxyResolutionFilter) {
  std::vector<std::string> proxy_list = {
      base::StringPrintf("%s%s", "http://", kLocalProxyHostPort),
      "http://test.proxy.com", "https://test.proxy.com", "direct://"};

  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  int fds[2];
  ASSERT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds[1]);
  adaptor_->system_services_worker_->OnProxyResolved("target_url", true,
                                                     proxy_list);

  brillo_loop_.RunOnce(false);

  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd.get(), &config));
  EXPECT_TRUE(config.has_proxy_resolution_reply());
  std::list<std::string> proxies;
  const worker::ProxyResolutionReply& reply = config.proxy_resolution_reply();
  for (auto const& proxy : reply.proxy_servers())
    proxies.push_back(proxy);

  EXPECT_EQ("target_url", reply.target_url());
  EXPECT_EQ(2, proxies.size());
  EXPECT_EQ("http://test.proxy.com", proxies.front());
}

// Test that verifies that authentication requests are result in sending a
// signal to notify credentials are missing and credentials and protection space
// if correctly forwarded to the worker processes.
TEST_F(SystemProxyAdaptorTest, ProtectionSpaceAuthenticationRequired) {
  EXPECT_CALL(*mock_exported_object_, SendSignal(_))
      .WillOnce(
          Invoke(this, &SystemProxyAdaptorTest::OnAuthenticationRequired));

  worker::ProtectionSpace protection_space;
  protection_space.set_origin("http://test.proxy.com");
  protection_space.set_realm("my realm");
  protection_space.set_scheme("basic");
  std::string msg;
  protection_space.SerializeToString(&msg);
  AddCredentialsToAuthCache(protection_space, kUser, kPassword);

  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  int fds[2];
  ASSERT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds[1]);
  adaptor_->RequestAuthenticationCredentials(protection_space,
                                             /* bad_credentials = */ false);

  brillo_loop_.RunOnce(false);

  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd.get(), &config));
  EXPECT_TRUE(config.has_credentials());

  const worker::Credentials& reply = config.credentials();
  EXPECT_TRUE(reply.has_protection_space());
  EXPECT_EQ(reply.username(), kUser);
  EXPECT_EQ(reply.password(), kPassword);
  EXPECT_EQ(reply.protection_space().SerializeAsString(),
            protection_space.SerializeAsString());
}

// Test that verifies that authentication requests that resolve to an empty
// credentials set are forwarded to the worker processes.
TEST_F(SystemProxyAdaptorTest, ProtectionSpaceNoCredentials) {
  EXPECT_CALL(*mock_exported_object_, SendSignal(_))
      .WillOnce(
          Invoke(this, &SystemProxyAdaptorTest::OnAuthenticationRequired));

  worker::ProtectionSpace protection_space;
  protection_space.set_origin("http://test.proxy.com");
  protection_space.set_realm("my realm");
  protection_space.set_scheme("basic");
  std::string msg;
  protection_space.SerializeToString(&msg);

  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  int fds[2];
  ASSERT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds[1]);
  adaptor_->RequestAuthenticationCredentials(protection_space,
                                             /* bad_credentials = */ false);

  brillo_loop_.RunOnce(false);

  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd.get(), &config));
  EXPECT_TRUE(config.has_credentials());

  const worker::Credentials& reply = config.credentials();
  EXPECT_TRUE(reply.has_protection_space());
  EXPECT_EQ(reply.username(), "");
  EXPECT_EQ(reply.password(), "");
  EXPECT_EQ(reply.protection_space().SerializeAsString(),
            protection_space.SerializeAsString());
}

TEST_F(SystemProxyAdaptorTest, ClearUserCredentials) {
  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  ASSERT_TRUE(adaptor_->system_services_worker_.get());

  int fds[2];
  ASSERT_TRUE(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_scoped_fd(fds[0]);
  // Reset the worker stdin pipe to read the input from the other endpoint.
  adaptor_->system_services_worker_->stdin_pipe_.reset(fds[1]);

  ClearUserCredentialsRequest request;
  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());
  adaptor_->ClearUserCredentials(proto_blob);
  brillo_loop_.RunOnce(false);

  // Expect that a request to clear user credentials has been sent to the
  // worker.
  worker::WorkerConfigs config;
  ASSERT_TRUE(ReadProtobuf(read_scoped_fd.get(), &config));
  EXPECT_TRUE(config.has_clear_user_credentials());
}

// Tests that the sandboxed worker is restarted if the request to clear the
// credentials fails.
TEST_F(SystemProxyAdaptorTest, ClearUserCredentialsRestartService) {
  EXPECT_CALL(*bus_, GetObjectProxy(patchpanel::kPatchPanelServiceName, _))
      .WillOnce(Return(mock_patchpanel_proxy_.get()));

  adaptor_->system_services_worker_ = adaptor_->CreateWorker();
  ASSERT_TRUE(adaptor_->system_services_worker_.get());
  EXPECT_EQ(1, adaptor_->create_worker_count_);

  ClearUserCredentialsRequest request;
  std::vector<uint8_t> proto_blob(request.ByteSizeLong());
  request.SerializeToArray(proto_blob.data(), proto_blob.size());
  // This request will fail because we didn't set up a communication pipe.
  adaptor_->ClearUserCredentials(proto_blob);
  brillo_loop_.RunOnce(false);

  ASSERT_TRUE(adaptor_->system_services_worker_.get());
  EXPECT_EQ(2, adaptor_->create_worker_count_);
}

// This test verifies that System-proxy correctly generates an NTLM
// authentication message based on a server challenge. The test data and
// expected result are taken from the chromium //net test code.
TEST_F(SystemProxyAdaptorTest, NtlmAuthMessageRequest) {
  NtlmAuthMessageRequest request;
  request.set_ntlmv2_enabled(true);
  request.set_mic_enabled(true);
  request.set_epa_enabled(true);
  request.set_domain(base::UTF16ToUTF8(net::ntlm::test::kNtlmDomain));
  request.set_username(base::UTF16ToUTF8(net::ntlm::test::kUser));
  request.set_hostname(net::ntlm::test::kHostnameAscii);
  request.set_channel_bindings(net::ntlm::test::kChannelBindings);
  request.set_spn(net::ntlm::test::kNtlmSpn);
  request.set_client_time(net::ntlm::test::kClientTimestamp);

  std::vector<uint8_t> client_challenge(
      std::begin(net::ntlm::test::kClientChallenge),
      std::end(net::ntlm::test::kClientChallenge));
  request.set_client_challenge(client_challenge.data(),
                               client_challenge.size());

  std::vector<uint8_t> server_challenge_message(
      std::begin(net::ntlm::test::kChallengeMsgFromSpecV2),
      std::end(net::ntlm::test::kChallengeMsgFromSpecV2));
  request.set_server_challenge_message(server_challenge_message.data(),
                                       server_challenge_message.size());
  GenerateNetworkAuthMessageRequest network_request;
  *network_request.mutable_ntlm_message_auth_request() = request;

  std::vector<uint8_t> proto_blob(network_request.ByteSizeLong());
  network_request.SerializeToArray(proto_blob.data(), proto_blob.size());
  proto_blob = adaptor_->GenerateNetworkAuthMessage(proto_blob);
  GenerateNetworkAuthMessageResponse response;
  network_request.SerializeToArray(proto_blob.data(), proto_blob.size());
  proto_blob = adaptor_->GenerateNetworkAuthMessage(proto_blob);
  ASSERT_TRUE(response.ParseFromArray(proto_blob.data(), proto_blob.size()));
  // Password is missing.
  EXPECT_FALSE(response.has_auth_message());

  // Set login the password.
  auto password_ptr = password_provider::test::CreatePassword(
      base::UTF16ToASCII(net::ntlm::test::kPassword));
  adaptor_->GetPasswordProvider()->SavePassword(*password_ptr);

  proto_blob.resize(network_request.ByteSizeLong());
  network_request.SerializeToArray(proto_blob.data(), proto_blob.size());
  proto_blob = adaptor_->GenerateNetworkAuthMessage(proto_blob);
  ASSERT_TRUE(response.ParseFromArray(proto_blob.data(), proto_blob.size()));
  EXPECT_TRUE(response.has_auth_message());
  std::vector<uint8_t> result(response.auth_message().begin(),
                              response.auth_message().end());
  ASSERT_EQ(base::size(net::ntlm::test::kExpectedAuthenticateMsgSpecResponseV2),
            result.size());
  ASSERT_EQ(0, memcmp(net::ntlm::test::kExpectedAuthenticateMsgSpecResponseV2,
                      result.data(), result.size()));
}

}  // namespace system_proxy
