// Copyright (c) 2012 The Chromium 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 "net/http/http_auth_handler_negotiate.h"

#include <string>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_request_info.h"
#include "net/http/mock_allow_http_auth_preferences.h"
#include "net/log/net_log_with_source.h"
#include "net/ssl/ssl_info.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

#if defined(OS_ANDROID)
#include "net/android/dummy_spnego_authenticator.h"
#elif defined(OS_WIN)
#include "net/http/mock_sspi_library_win.h"
#elif defined(OS_POSIX)
#include "net/http/mock_gssapi_library_posix.h"
#endif

using net::test::IsError;
using net::test::IsOk;

namespace net {

constexpr char kFakeToken[] = "FakeToken";

#if defined(OS_ANDROID)
typedef net::android::DummySpnegoAuthenticator MockAuthLibrary;
#elif defined(OS_WIN)
typedef MockSSPILibrary MockAuthLibrary;
#elif defined(OS_POSIX)
typedef test::MockGSSAPILibrary MockAuthLibrary;
#endif

class HttpAuthHandlerNegotiateTest : public PlatformTest,
                                     public WithScopedTaskEnvironment {
 public:
  void SetUp() override {
    auth_library_ = new MockAuthLibrary();
    resolver_.reset(new MockHostResolver());
    resolver_->rules_map()[HostResolverSource::ANY]->AddIPLiteralRule(
        "alias", "10.0.0.2", "canonical.example.com");

    http_auth_preferences_.reset(new MockAllowHttpAuthPreferences());
    factory_.reset(new HttpAuthHandlerNegotiate::Factory(
        net::HttpAuthHandlerFactory::NegotiateAuthSystemFactory()));
    factory_->set_http_auth_preferences(http_auth_preferences_.get());
#if defined(OS_ANDROID)
    http_auth_preferences_->set_auth_android_negotiate_account_type(
        "org.chromium.test.DummySpnegoAuthenticator");
    MockAuthLibrary::EnsureTestAccountExists();
#endif
#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_ANDROID))
    factory_->set_library(base::WrapUnique(auth_library_));
#endif
  }

#if defined(OS_ANDROID)
  void TearDown() override { MockAuthLibrary::RemoveTestAccounts(); }
#endif

  void SetupMocks(MockAuthLibrary* mock_library) {
#if defined(OS_WIN)
    security_package_.reset(new SecPkgInfoW);
    memset(security_package_.get(), 0x0, sizeof(SecPkgInfoW));
    security_package_->cbMaxToken = 1337;
    mock_library->ExpectQuerySecurityPackageInfo(
        L"Negotiate", SEC_E_OK, security_package_.get());
#elif defined(OS_POSIX)
    // Copied from an actual transaction!
    static const char kAuthResponse[] =
        "\x60\x82\x02\xCA\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01"
        "\x00\x6E\x82\x02\xB9\x30\x82\x02\xB5\xA0\x03\x02\x01\x05\xA1\x03"
        "\x02\x01\x0E\xA2\x07\x03\x05\x00\x00\x00\x00\x00\xA3\x82\x01\xC1"
        "\x61\x82\x01\xBD\x30\x82\x01\xB9\xA0\x03\x02\x01\x05\xA1\x16\x1B"
        "\x14\x55\x4E\x49\x58\x2E\x43\x4F\x52\x50\x2E\x47\x4F\x4F\x47\x4C"
        "\x45\x2E\x43\x4F\x4D\xA2\x2C\x30\x2A\xA0\x03\x02\x01\x01\xA1\x23"
        "\x30\x21\x1B\x04\x68\x6F\x73\x74\x1B\x19\x6E\x69\x6E\x6A\x61\x2E"
        "\x63\x61\x6D\x2E\x63\x6F\x72\x70\x2E\x67\x6F\x6F\x67\x6C\x65\x2E"
        "\x63\x6F\x6D\xA3\x82\x01\x6A\x30\x82\x01\x66\xA0\x03\x02\x01\x10"
        "\xA1\x03\x02\x01\x01\xA2\x82\x01\x58\x04\x82\x01\x54\x2C\xB1\x2B"
        "\x0A\xA5\xFF\x6F\xEC\xDE\xB0\x19\x6E\x15\x20\x18\x0C\x42\xB3\x2C"
        "\x4B\xB0\x37\x02\xDE\xD3\x2F\xB4\xBF\xCA\xEC\x0E\xF9\xF3\x45\x6A"
        "\x43\xF3\x8D\x79\xBD\xCB\xCD\xB2\x2B\xB8\xFC\xD6\xB4\x7F\x09\x48"
        "\x14\xA7\x4F\xD2\xEE\xBC\x1B\x2F\x18\x3B\x81\x97\x7B\x28\xA4\xAF"
        "\xA8\xA3\x7A\x31\x1B\xFC\x97\xB6\xBA\x8A\x50\x50\xD7\x44\xB8\x30"
        "\xA4\x51\x4C\x3A\x95\x6C\xA1\xED\xE2\xEF\x17\xFE\xAB\xD2\xE4\x70"
        "\xDE\xEB\x7E\x86\x48\xC5\x3E\x19\x5B\x83\x17\xBB\x52\x26\xC0\xF3"
        "\x38\x0F\xB0\x8C\x72\xC9\xB0\x8B\x99\x96\x18\xE1\x9E\x67\x9D\xDC"
        "\xF5\x39\x80\x70\x35\x3F\x98\x72\x16\x44\xA2\xC0\x10\xAA\x70\xBD"
        "\x06\x6F\x83\xB1\xF4\x67\xA4\xBD\xDA\xF7\x79\x1D\x96\xB5\x7E\xF8"
        "\xC6\xCF\xB4\xD9\x51\xC9\xBB\xB4\x20\x3C\xDD\xB9\x2C\x38\xEA\x40"
        "\xFB\x02\x6C\xCB\x48\x71\xE8\xF4\x34\x5B\x63\x5D\x13\x57\xBD\xD1"
        "\x3D\xDE\xE8\x4A\x51\x6E\xBE\x4C\xF5\xA3\x84\xF7\x4C\x4E\x58\x04"
        "\xBE\xD1\xCC\x22\xA0\x43\xB0\x65\x99\x6A\xE0\x78\x0D\xFC\xE1\x42"
        "\xA9\x18\xCF\x55\x4D\x23\xBD\x5C\x0D\xB5\x48\x25\x47\xCC\x01\x54"
        "\x36\x4D\x0C\x6F\xAC\xCD\x33\x21\xC5\x63\x18\x91\x68\x96\xE9\xD1"
        "\xD8\x23\x1F\x21\xAE\x96\xA3\xBD\x27\xF7\x4B\xEF\x4C\x43\xFF\xF8"
        "\x22\x57\xCF\x68\x6C\x35\xD5\x21\x48\x5B\x5F\x8F\xA5\xB9\x6F\x99"
        "\xA6\xE0\x6E\xF0\xC5\x7C\x91\xC8\x0B\x8A\x4B\x4E\x80\x59\x02\xE9"
        "\xE8\x3F\x87\x04\xA6\xD1\xCA\x26\x3C\xF0\xDA\x57\xFA\xE6\xAF\x25"
        "\x43\x34\xE1\xA4\x06\x1A\x1C\xF4\xF5\x21\x9C\x00\x98\xDD\xF0\xB4"
        "\x8E\xA4\x81\xDA\x30\x81\xD7\xA0\x03\x02\x01\x10\xA2\x81\xCF\x04"
        "\x81\xCC\x20\x39\x34\x60\x19\xF9\x4C\x26\x36\x46\x99\x7A\xFD\x2B"
        "\x50\x8B\x2D\x47\x72\x38\x20\x43\x0E\x6E\x28\xB3\xA7\x4F\x26\xF1"
        "\xF1\x7B\x02\x63\x58\x5A\x7F\xC8\xD0\x6E\xF5\xD1\xDA\x28\x43\x1B"
        "\x6D\x9F\x59\x64\xDE\x90\xEA\x6C\x8C\xA9\x1B\x1E\x92\x29\x24\x23"
        "\x2C\xE3\xEA\x64\xEF\x91\xA5\x4E\x94\xE1\xDC\x56\x3A\xAF\xD5\xBC"
        "\xC9\xD3\x9B\x6B\x1F\xBE\x40\xE5\x40\xFF\x5E\x21\xEA\xCE\xFC\xD5"
        "\xB0\xE5\xBA\x10\x94\xAE\x16\x54\xFC\xEB\xAB\xF1\xD4\x20\x31\xCC"
        "\x26\xFE\xBE\xFE\x22\xB6\x9B\x1A\xE5\x55\x2C\x93\xB7\x3B\xD6\x4C"
        "\x35\x35\xC1\x59\x61\xD4\x1F\x2E\x4C\xE1\x72\x8F\x71\x4B\x0C\x39"
        "\x80\x79\xFA\xCD\xEA\x71\x1B\xAE\x35\x41\xED\xF9\x65\x0C\x59\xF8"
        "\xE1\x27\xDA\xD6\xD1\x20\x32\xCD\xBF\xD1\xEF\xE2\xED\xAD\x5D\xA7"
        "\x69\xE3\x55\xF9\x30\xD3\xD4\x08\xC8\xCA\x62\xF8\x64\xEC\x9B\x92"
        "\x1A\xF1\x03\x2E\xCC\xDC\xEB\x17\xDE\x09\xAC\xA9\x58\x86";
    test::GssContextMockImpl context1(
        "localhost",                         // Source name
        "example.com",                       // Target name
        23,                                  // Lifetime
        *CHROME_GSS_SPNEGO_MECH_OID_DESC,    // Mechanism
        0,                                   // Context flags
        1,                                   // Locally initiated
        0);                                  // Open
    test::GssContextMockImpl context2(
        "localhost",                         // Source name
        "example.com",                       // Target name
        23,                                  // Lifetime
        *CHROME_GSS_SPNEGO_MECH_OID_DESC,    // Mechanism
        0,                                   // Context flags
        1,                                   // Locally initiated
        1);                                  // Open
    MockAuthLibrary::SecurityContextQuery queries[] = {
        MockAuthLibrary::SecurityContextQuery(
            "Negotiate",            // Package name
            GSS_S_CONTINUE_NEEDED,  // Major response code
            0,                      // Minor response code
            context1,               // Context
            nullptr,                // Expected input token
            kAuthResponse),         // Output token
        MockAuthLibrary::SecurityContextQuery(
            "Negotiate",     // Package name
            GSS_S_COMPLETE,  // Major response code
            0,               // Minor response code
            context2,        // Context
            kAuthResponse,   // Expected input token
            kAuthResponse)   // Output token
    };

    for (size_t i = 0; i < base::size(queries); ++i) {
      mock_library->ExpectSecurityContext(queries[i].expected_package,
                                          queries[i].response_code,
                                          queries[i].minor_response_code,
                                          queries[i].context_info,
                                          queries[i].expected_input_token,
                                          queries[i].output_token);
    }
#endif  // defined(OS_POSIX)
  }

#if defined(OS_POSIX)
  void SetupErrorMocks(MockAuthLibrary* mock_library,
                       int major_status,
                       int minor_status) {
    const gss_OID_desc kDefaultMech = {0, nullptr};
    test::GssContextMockImpl context(
        "localhost",                    // Source name
        "example.com",                  // Target name
        0,                              // Lifetime
        kDefaultMech,                   // Mechanism
        0,                              // Context flags
        1,                              // Locally initiated
        0);                             // Open
    MockAuthLibrary::SecurityContextQuery query(
        "Negotiate",   // Package name
        major_status,  // Major response code
        minor_status,  // Minor response code
        context,       // Context
        nullptr,       // Expected input token
        nullptr);      // Output token

    mock_library->ExpectSecurityContext(query.expected_package,
                                        query.response_code,
                                        query.minor_response_code,
                                        query.context_info,
                                        query.expected_input_token,
                                        query.output_token);
  }

#endif  // defined(OS_POSIX)

  int CreateHandler(bool disable_cname_lookup,
                    bool use_port,
                    bool synchronous_resolve_mode,
                    const std::string& url_string,
                    std::unique_ptr<HttpAuthHandlerNegotiate>* handler) {
    http_auth_preferences_->set_negotiate_disable_cname_lookup(
        disable_cname_lookup);
    http_auth_preferences_->set_negotiate_enable_port(use_port);
    resolver_->set_synchronous_mode(synchronous_resolve_mode);
    GURL gurl(url_string);

    // Note: This is a little tricky because CreateAuthHandlerFromString
    // expects a std::unique_ptr<HttpAuthHandler>* rather than a
    // std::unique_ptr<HttpAuthHandlerNegotiate>*. This needs to do the cast
    // after creating the handler, and make sure that generic_handler
    // no longer holds on to the HttpAuthHandlerNegotiate object.
    std::unique_ptr<HttpAuthHandler> generic_handler;
    SSLInfo null_ssl_info;
    int rv = factory_->CreateAuthHandlerFromString(
        "Negotiate", HttpAuth::AUTH_SERVER, null_ssl_info, gurl,
        NetLogWithSource(), resolver_.get(), &generic_handler);
    if (rv != OK)
      return rv;
    HttpAuthHandlerNegotiate* negotiate_handler =
        static_cast<HttpAuthHandlerNegotiate*>(generic_handler.release());
    handler->reset(negotiate_handler);
    return rv;
  }

  MockAuthLibrary* AuthLibrary() { return auth_library_; }
  MockHostResolver* resolver() { return resolver_.get(); }
  MockAllowHttpAuthPreferences* http_auth_preferences() {
    return http_auth_preferences_.get();
  }

 private:
#if defined(OS_WIN)
  std::unique_ptr<SecPkgInfoW> security_package_;
#endif
  // |auth_library_| is passed to |factory_|, which assumes ownership of it, but
  // can't be a scoped pointer to it since the tests need access when they set
  // up the mocks after passing ownership.
  MockAuthLibrary* auth_library_;
  std::unique_ptr<MockHostResolver> resolver_;
  std::unique_ptr<MockAllowHttpAuthPreferences> http_auth_preferences_;
  std::unique_ptr<HttpAuthHandlerNegotiate::Factory> factory_;
};

TEST_F(HttpAuthHandlerNegotiateTest, DisableCname) {
  SetupMocks(AuthLibrary());
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      true, false, true, "http://alias:500", &auth_handler));

  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(OK, callback.GetResult(auth_handler->GenerateAuthToken(
                    nullptr, &request_info, callback.callback(), &token)));
#if defined(OS_WIN)
  EXPECT_EQ("HTTP/alias", auth_handler->spn_for_testing());
#elif defined(OS_POSIX)
  EXPECT_EQ("HTTP@alias", auth_handler->spn_for_testing());
#endif
}

TEST_F(HttpAuthHandlerNegotiateTest, DisableCnameStandardPort) {
  SetupMocks(AuthLibrary());
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      true, true, true, "http://alias:80", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(OK, callback.GetResult(auth_handler->GenerateAuthToken(
                    nullptr, &request_info, callback.callback(), &token)));
#if defined(OS_WIN)
  EXPECT_EQ("HTTP/alias", auth_handler->spn_for_testing());
#elif defined(OS_POSIX)
  EXPECT_EQ("HTTP@alias", auth_handler->spn_for_testing());
#endif
}

TEST_F(HttpAuthHandlerNegotiateTest, DisableCnameNonstandardPort) {
  SetupMocks(AuthLibrary());
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      true, true, true, "http://alias:500", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(OK, callback.GetResult(auth_handler->GenerateAuthToken(
                    nullptr, &request_info, callback.callback(), &token)));
#if defined(OS_WIN)
  EXPECT_EQ("HTTP/alias:500", auth_handler->spn_for_testing());
#elif defined(OS_POSIX)
  EXPECT_EQ("HTTP@alias:500", auth_handler->spn_for_testing());
#endif
}

TEST_F(HttpAuthHandlerNegotiateTest, CnameSync) {
  SetupMocks(AuthLibrary());
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      false, false, true, "http://alias:500", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(OK, callback.GetResult(auth_handler->GenerateAuthToken(
                    nullptr, &request_info, callback.callback(), &token)));
#if defined(OS_WIN)
  EXPECT_EQ("HTTP/canonical.example.com", auth_handler->spn_for_testing());
#elif defined(OS_POSIX)
  EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn_for_testing());
#endif
}

TEST_F(HttpAuthHandlerNegotiateTest, CnameAsync) {
  SetupMocks(AuthLibrary());
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      false, false, false, "http://alias:500", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(ERR_IO_PENDING,
            auth_handler->GenerateAuthToken(nullptr, &request_info,
                                            callback.callback(), &token));
  EXPECT_THAT(callback.WaitForResult(), IsOk());
#if defined(OS_WIN)
  EXPECT_EQ("HTTP/canonical.example.com", auth_handler->spn_for_testing());
#elif defined(OS_POSIX)
  EXPECT_EQ("HTTP@canonical.example.com", auth_handler->spn_for_testing());
#endif
}

#if defined(OS_POSIX)

// This test is only for GSSAPI, as we can't use explicit credentials with
// that library.
TEST_F(HttpAuthHandlerNegotiateTest, ServerNotInKerberosDatabase) {
  SetupErrorMocks(AuthLibrary(), GSS_S_FAILURE, 0x96C73A07);  // No server
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      false, false, false, "http://alias:500", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(ERR_IO_PENDING,
            auth_handler->GenerateAuthToken(nullptr, &request_info,
                                            callback.callback(), &token));
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_MISSING_AUTH_CREDENTIALS));
}

// This test is only for GSSAPI, as we can't use explicit credentials with
// that library.
TEST_F(HttpAuthHandlerNegotiateTest, NoKerberosCredentials) {
  SetupErrorMocks(AuthLibrary(), GSS_S_FAILURE, 0x96C73AC3);  // No credentials
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  EXPECT_EQ(OK, CreateHandler(
      false, false, false, "http://alias:500", &auth_handler));
  ASSERT_TRUE(auth_handler.get() != nullptr);
  TestCompletionCallback callback;
  HttpRequestInfo request_info;
  std::string token;
  EXPECT_EQ(ERR_IO_PENDING,
            auth_handler->GenerateAuthToken(nullptr, &request_info,
                                            callback.callback(), &token));
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_MISSING_AUTH_CREDENTIALS));
}

#if defined(DLOPEN_KERBEROS)
TEST_F(HttpAuthHandlerNegotiateTest, MissingGSSAPI) {
  std::unique_ptr<HostResolver> host_resolver(new MockHostResolver());
  MockAllowHttpAuthPreferences http_auth_preferences;
  std::unique_ptr<HttpAuthHandlerNegotiate::Factory> negotiate_factory(
      new HttpAuthHandlerNegotiate::Factory(
          net::HttpAuthHandlerFactory::NegotiateAuthSystemFactory()));
  negotiate_factory->set_host_resolver(host_resolver);
  negotiate_factory->set_http_auth_preferences(&http_auth_preferences);
  negotiate_factory->set_library(
      std::make_unique<GSSAPISharedLibrary>("/this/library/does/not/exist"));

  GURL gurl("http://www.example.com");
  std::unique_ptr<HttpAuthHandler> generic_handler;
  int rv = negotiate_factory->CreateAuthHandlerFromString(
      "Negotiate", HttpAuth::AUTH_SERVER, gurl, NetLogWithSource(),
      &generic_handler);
  EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME));
  EXPECT_TRUE(generic_handler.get() == nullptr);
}
#endif  // defined(DLOPEN_KERBEROS)

// AllowGssapiLibraryLoad() is only supported on Chrome OS.
#if defined(OS_CHROMEOS)
TEST_F(HttpAuthHandlerNegotiateTest, AllowGssapiLibraryLoad) {
  // Disabling allow_gssapi_library_load should prevent handler creation.
  SetupMocks(AuthLibrary());
  http_auth_preferences()->set_allow_gssapi_library_load(false);
  std::unique_ptr<HttpAuthHandlerNegotiate> auth_handler;
  int rv = CreateHandler(true, false, true, "http://alias:500", &auth_handler);
  EXPECT_THAT(rv, IsError(ERR_UNSUPPORTED_AUTH_SCHEME));
  EXPECT_FALSE(auth_handler);

  // Handler creation can be dynamically re-enabled.
  http_auth_preferences()->set_allow_gssapi_library_load(true);
  rv = CreateHandler(true, false, true, "http://alias:500", &auth_handler);
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(auth_handler);
}
#endif  // defined(OS_CHROMEOS)

#endif  // defined(OS_POSIX)

class TestAuthSystem : public HttpNegotiateAuthSystem {
 public:
  TestAuthSystem() = default;
  ~TestAuthSystem() override = default;

  // HttpNegotiateAuthSystem implementation:
  bool Init() override { return true; }
  bool NeedsIdentity() const override { return true; }
  bool AllowsExplicitCredentials() const override { return true; }

  net::HttpAuth::AuthorizationResult ParseChallenge(
      net::HttpAuthChallengeTokenizer* tok) override {
    return net::HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
  }

  int GenerateAuthToken(const net::AuthCredentials* credentials,
                        const std::string& spn,
                        const std::string& channel_bindings,
                        std::string* auth_token,
                        net::CompletionOnceCallback callback) override {
    *auth_token = kFakeToken;
    return net::OK;
  }

  void SetDelegation(HttpAuth::DelegationType delegation_type) override {}
};

TEST_F(HttpAuthHandlerNegotiateTest, OverrideAuthSystem) {
  auto negotiate_factory = std::make_unique<HttpAuthHandlerNegotiate::Factory>(
      base::BindRepeating([](const HttpAuthPreferences*)
                              -> std::unique_ptr<HttpNegotiateAuthSystem> {
        return std::make_unique<TestAuthSystem>();
      }));
  negotiate_factory->set_http_auth_preferences(http_auth_preferences());
#if !defined(OS_ANDROID)
  auto auth_library = std::make_unique<MockAuthLibrary>();
  SetupMocks(auth_library.get());
  negotiate_factory->set_library(std::move(auth_library));
#endif

  GURL gurl("http://www.example.com");
  std::unique_ptr<HttpAuthHandler> handler;
  EXPECT_EQ(OK, negotiate_factory->CreateAuthHandlerFromString(
                    "Negotiate", HttpAuth::AUTH_SERVER, SSLInfo(), gurl,
                    NetLogWithSource(), resolver(), &handler));
  EXPECT_TRUE(handler);

  TestCompletionCallback callback;
  std::string auth_token;
  HttpRequestInfo request_info;
  EXPECT_EQ(OK, callback.GetResult(handler->GenerateAuthToken(
                    nullptr, &request_info, callback.callback(), &auth_token)));
  EXPECT_EQ(kFakeToken, auth_token);
}

}  // namespace net
