// Copyright (c) 2010 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/mock_sspi_library_win.h"

#include <algorithm>
#include <cstring>
#include <memory>

#include "base/logging.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"

// Comparator so we can use CredHandle and CtxtHandle with std::set. Both of
// those classes are typedefs for _SecHandle.
bool operator<(const _SecHandle left, const _SecHandle right) {
  return left.dwUpper < right.dwUpper || left.dwLower < right.dwLower;
}

namespace net {

namespace {

int uniquifier_ = 0;

struct MockCredential {
  base::string16 source_principal;
  base::string16 package;
  bool has_explicit_credentials = false;
  int uniquifier = ++uniquifier_;

  // CredHandle and CtxtHandle both shared the following definition:
  //
  // typedef struct _SecHandle {
  //   ULONG_PTR       dwLower;
  //   ULONG_PTR       dwUpper;
  // } SecHandle, * PSecHandle;
  //
  // ULONG_PTR type can hold a pointer. This function stuffs |this| into dwUpper
  // and adds a uniquifier to dwLower. This ensures that all PCredHandles issued
  // by this method during the lifetime of this process is unique.
  void StoreInHandle(PCredHandle handle) {
    DCHECK(uniquifier > 0);
    EXPECT_FALSE(SecIsValidHandle(handle));

    handle->dwLower = uniquifier;
    handle->dwUpper = reinterpret_cast<ULONG_PTR>(this);

    DCHECK(SecIsValidHandle(handle));
  }

  static MockCredential* FromHandle(PCredHandle handle) {
    return reinterpret_cast<MockCredential*>(handle->dwUpper);
  }
};

struct MockContext {
  MockCredential* credential = nullptr;
  base::string16 target_principal;
  int uniquifier = ++uniquifier_;
  int rounds = 0;

  // CredHandle and CtxtHandle both shared the following definition:
  //
  // typedef struct _SecHandle {
  //   ULONG_PTR       dwLower;
  //   ULONG_PTR       dwUpper;
  // } SecHandle, * PSecHandle;
  //
  // ULONG_PTR type can hold a pointer. This function stuffs |this| into dwUpper
  // and adds a uniquifier to dwLower. This ensures that all PCredHandles issued
  // by this method during the lifetime of this process is unique.
  void StoreInHandle(PCtxtHandle handle) {
    EXPECT_FALSE(SecIsValidHandle(handle));
    DCHECK(uniquifier > 0);

    handle->dwLower = uniquifier;
    handle->dwUpper = reinterpret_cast<ULONG_PTR>(this);

    DCHECK(SecIsValidHandle(handle));
  }

  std::string ToString() const {
    return base::StringPrintf(
        "%s's token #%d for %S",
        base::UTF16ToUTF8(credential->source_principal).c_str(), rounds + 1,
        base::as_wcstr(target_principal));
  }

  static MockContext* FromHandle(PCtxtHandle handle) {
    return reinterpret_cast<MockContext*>(handle->dwUpper);
  }
};

}  // namespace

MockSSPILibrary::MockSSPILibrary() {
}

MockSSPILibrary::~MockSSPILibrary() {
  EXPECT_TRUE(expected_package_queries_.empty());
  EXPECT_TRUE(expected_freed_packages_.empty());
  EXPECT_TRUE(active_credentials_.empty());
  EXPECT_TRUE(active_contexts_.empty());
}

SECURITY_STATUS MockSSPILibrary::AcquireCredentialsHandle(
    LPWSTR pszPrincipal,
    LPWSTR pszPackage,
    unsigned long fCredentialUse,
    void* pvLogonId,
    void* pvAuthData,
    SEC_GET_KEY_FN pGetKeyFn,
    void* pvGetKeyArgument,
    PCredHandle phCredential,
    PTimeStamp ptsExpiry) {
  DCHECK(!SecIsValidHandle(phCredential));
  auto* credential = new MockCredential;
  credential->source_principal = pszPrincipal ? base::as_u16cstr(pszPrincipal)
                                              : STRING16_LITERAL("<Default>");
  credential->package = base::as_u16cstr(pszPackage);
  credential->has_explicit_credentials = !!pvAuthData;

  credential->StoreInHandle(phCredential);

  if (ptsExpiry) {
    ptsExpiry->LowPart = 0xBAA5B780;
    ptsExpiry->HighPart = 0x01D54E17;
  }

  active_credentials_.insert(*phCredential);
  return SEC_E_OK;
}

SECURITY_STATUS MockSSPILibrary::InitializeSecurityContext(
    PCredHandle phCredential,
    PCtxtHandle phContext,
    SEC_WCHAR* pszTargetName,
    unsigned long fContextReq,
    unsigned long Reserved1,
    unsigned long TargetDataRep,
    PSecBufferDesc pInput,
    unsigned long Reserved2,
    PCtxtHandle phNewContext,
    PSecBufferDesc pOutput,
    unsigned long* contextAttr,
    PTimeStamp ptsExpiry) {
  MockContext* new_context = new MockContext;
  new_context->credential = MockCredential::FromHandle(phCredential);
  new_context->target_principal = base::as_u16cstr(pszTargetName);
  new_context->rounds = 0;

  // Always rotate contexts. That way tests will fail if the caller's context
  // management is broken.
  if (phContext && SecIsValidHandle(phContext)) {
    std::unique_ptr<MockContext> old_context{
        MockContext::FromHandle(phContext)};
    EXPECT_EQ(old_context->credential, new_context->credential);
    EXPECT_EQ(1u, active_contexts_.erase(*phContext));

    new_context->rounds = old_context->rounds + 1;
    SecInvalidateHandle(phContext);
  }

  new_context->StoreInHandle(phNewContext);
  active_contexts_.insert(*phNewContext);

  auto token = new_context->ToString();
  PSecBuffer out_buffer = pOutput->pBuffers;
  out_buffer->cbBuffer = std::min<ULONG>(out_buffer->cbBuffer, token.size());
  std::memcpy(out_buffer->pvBuffer, token.data(), out_buffer->cbBuffer);

  if (ptsExpiry) {
    ptsExpiry->LowPart = 0xBAA5B780;
    ptsExpiry->HighPart = 0x01D54E15;
  }
  return SEC_E_OK;
}

SECURITY_STATUS MockSSPILibrary::QueryContextAttributesEx(PCtxtHandle phContext,
                                                          ULONG ulAttribute,
                                                          PVOID pBuffer,
                                                          ULONG cbBuffer) {
  static const SecPkgInfoW kNegotiatedPackage = {
      0,
      0,
      0,
      0,
      const_cast<SEC_WCHAR*>(L"Itsa me Kerberos!!"),
      const_cast<SEC_WCHAR*>(L"I like turtles")};

  auto* context = MockContext::FromHandle(phContext);

  switch (ulAttribute) {
    case SECPKG_ATTR_NATIVE_NAMES: {
      auto* native_names =
          reinterpret_cast<SecPkgContext_NativeNames*>(pBuffer);
      DCHECK_EQ(sizeof(*native_names), cbBuffer);
      native_names->sClientName =
          base::as_writable_wcstr(context->credential->source_principal);
      native_names->sServerName =
          base::as_writable_wcstr(context->target_principal);
      return SEC_E_OK;
    }

    case SECPKG_ATTR_NEGOTIATION_INFO: {
      auto* negotiation_info =
          reinterpret_cast<SecPkgContext_NegotiationInfo*>(pBuffer);
      DCHECK_EQ(sizeof(*negotiation_info), cbBuffer);
      negotiation_info->PackageInfo =
          const_cast<SecPkgInfoW*>(&kNegotiatedPackage);
      negotiation_info->NegotiationState = (context->rounds == 1)
                                               ? SECPKG_NEGOTIATION_COMPLETE
                                               : SECPKG_NEGOTIATION_IN_PROGRESS;
      return SEC_E_OK;
    }

    case SECPKG_ATTR_AUTHORITY: {
      auto* authority = reinterpret_cast<SecPkgContext_Authority*>(pBuffer);
      DCHECK_EQ(sizeof(*authority), cbBuffer);
      authority->sAuthorityName = const_cast<SEC_WCHAR*>(L"Dodgy Server");
      return SEC_E_OK;
    }

    default:
      return SEC_E_UNSUPPORTED_FUNCTION;
  }
}

SECURITY_STATUS MockSSPILibrary::QuerySecurityPackageInfo(
    LPWSTR pszPackageName, PSecPkgInfoW *pkgInfo) {
  EXPECT_TRUE(!expected_package_queries_.empty());
  PackageQuery package_query = expected_package_queries_.front();
  expected_package_queries_.pop_front();
  std::wstring actual_package(pszPackageName);
  EXPECT_EQ(package_query.expected_package, actual_package);
  *pkgInfo = package_query.package_info;
  if (package_query.response_code == SEC_E_OK)
    expected_freed_packages_.insert(package_query.package_info);
  return package_query.response_code;
}

SECURITY_STATUS MockSSPILibrary::FreeCredentialsHandle(
    PCredHandle phCredential) {
  DCHECK(SecIsValidHandle(phCredential));
  EXPECT_EQ(1u, active_credentials_.erase(*phCredential));
  std::unique_ptr<MockCredential> owned{
      MockCredential::FromHandle(phCredential)};
  SecInvalidateHandle(phCredential);
  return SEC_E_OK;
}

SECURITY_STATUS MockSSPILibrary::DeleteSecurityContext(PCtxtHandle phContext) {
  std::unique_ptr<MockContext> context{MockContext::FromHandle(phContext)};
  EXPECT_EQ(1u, active_contexts_.erase(*phContext));
  SecInvalidateHandle(phContext);
  return SEC_E_OK;
}

SECURITY_STATUS MockSSPILibrary::FreeContextBuffer(PVOID pvContextBuffer) {
  PSecPkgInfoW package_info = static_cast<PSecPkgInfoW>(pvContextBuffer);
  std::set<PSecPkgInfoW>::iterator it = expected_freed_packages_.find(
      package_info);
  EXPECT_TRUE(it != expected_freed_packages_.end());
  expected_freed_packages_.erase(it);
  return SEC_E_OK;
}

void MockSSPILibrary::ExpectQuerySecurityPackageInfo(
    const std::wstring& expected_package,
    SECURITY_STATUS response_code,
    PSecPkgInfoW package_info) {
  PackageQuery package_query = {expected_package, response_code,
                                package_info};
  expected_package_queries_.push_back(package_query);
}

}  // namespace net
