// Copyright 2016 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/win/registration_protocol_win.h"

#include <aclapi.h>
#include <sddl.h>
#include <string.h>
#include <windows.h>

#include <vector>

#include "base/logging.h"
#include "base/strings/string16.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "util/win/scoped_handle.h"
#include "util/win/scoped_local_alloc.h"

namespace crashpad {
namespace test {
namespace {

base::string16 GetStringFromSid(PSID sid) {
  LPWSTR sid_str;
  if (!ConvertSidToStringSid(sid, &sid_str)) {
    PLOG(ERROR) << "ConvertSidToStringSid";
    return base::string16();
  }
  ScopedLocalAlloc sid_str_ptr(sid_str);
  return sid_str;
}

base::string16 GetUserSidString() {
  HANDLE token_handle;
  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_handle)) {
    PLOG(ERROR) << "OpenProcessToken";
    return base::string16();
  }

  ScopedKernelHANDLE token(token_handle);
  DWORD user_size = 0;
  GetTokenInformation(token.get(), TokenUser, nullptr, 0, &user_size);
  if (user_size == 0) {
    PLOG(ERROR) << "GetTokenInformation Size";
    return base::string16();
  }

  std::vector<char> user(user_size);
  if (!GetTokenInformation(
          token.get(), TokenUser, user.data(), user_size, &user_size)) {
    PLOG(ERROR) << "GetTokenInformation";
    return base::string16();
  }

  TOKEN_USER* user_ptr = reinterpret_cast<TOKEN_USER*>(user.data());
  return GetStringFromSid(user_ptr->User.Sid);
}

void CheckAce(PACL acl,
              DWORD index,
              BYTE check_ace_type,
              ACCESS_MASK check_mask,
              const base::string16& check_sid) {
  ASSERT_FALSE(check_sid.empty());
  void* ace_ptr;
  ASSERT_TRUE(GetAce(acl, index, &ace_ptr));

  ACE_HEADER* header = static_cast<ACE_HEADER*>(ace_ptr);
  ASSERT_EQ(check_ace_type, header->AceType);
  ASSERT_EQ(0, header->AceFlags);

  PSID sid = nullptr;
  ACCESS_MASK mask = 0;
  switch (header->AceType) {
    case ACCESS_ALLOWED_ACE_TYPE: {
      ACCESS_ALLOWED_ACE* allowed_ace =
          static_cast<ACCESS_ALLOWED_ACE*>(ace_ptr);
      sid = &allowed_ace->SidStart;
      mask = allowed_ace->Mask;
    } break;
    case SYSTEM_MANDATORY_LABEL_ACE_TYPE: {
      SYSTEM_MANDATORY_LABEL_ACE* label_ace =
          static_cast<SYSTEM_MANDATORY_LABEL_ACE*>(ace_ptr);
      sid = &label_ace->SidStart;
      mask = label_ace->Mask;
    } break;
    default:
      NOTREACHED();
      break;
  }

  ASSERT_EQ(check_mask, mask);
  ASSERT_EQ(check_sid, GetStringFromSid(sid));
}

TEST(SecurityDescriptor, NamedPipeDefault) {
  const void* sec_desc = GetSecurityDescriptorForNamedPipeInstance(nullptr);

  PACL acl;
  BOOL acl_present;
  BOOL acl_defaulted;
  ASSERT_TRUE(GetSecurityDescriptorDacl(
      const_cast<void*>(sec_desc), &acl_present, &acl, &acl_defaulted));
  ASSERT_EQ(3, acl->AceCount);
  CheckAce(acl, 0, ACCESS_ALLOWED_ACE_TYPE, GENERIC_ALL, GetUserSidString());
  // Check SYSTEM user SID.
  CheckAce(acl, 1, ACCESS_ALLOWED_ACE_TYPE, GENERIC_ALL, L"S-1-5-18");
  // Check ALL APPLICATION PACKAGES group SID.
  CheckAce(acl,
           2,
           ACCESS_ALLOWED_ACE_TYPE,
           GENERIC_READ | GENERIC_WRITE,
           L"S-1-15-2-1");

  ASSERT_TRUE(GetSecurityDescriptorSacl(
      const_cast<void*>(sec_desc), &acl_present, &acl, &acl_defaulted));
  ASSERT_EQ(1, acl->AceCount);
  CheckAce(acl, 0, SYSTEM_MANDATORY_LABEL_ACE_TYPE, 0, L"S-1-16-0");
}

TEST(SecurityDescriptor, MatchesAdvapi32) {
  // This security descriptor is built manually in the connection code to avoid
  // calling the advapi32 functions. Verify that it returns the same thing as
  // ConvertStringSecurityDescriptorToSecurityDescriptor() would.

  // Mandatory Label, no ACE flags, no ObjectType, integrity level
  // untrusted.
  static constexpr wchar_t kSddl[] = L"S:(ML;;;;;S-1-16-0)";
  PSECURITY_DESCRIPTOR sec_desc;
  ULONG sec_desc_len;
  ASSERT_TRUE(ConvertStringSecurityDescriptorToSecurityDescriptor(
      kSddl, SDDL_REVISION_1, &sec_desc, &sec_desc_len))
      << ErrorMessage("ConvertStringSecurityDescriptorToSecurityDescriptor");
  ScopedLocalAlloc sec_desc_owner(sec_desc);

  size_t created_len;
  const void* const created =
      GetFallbackSecurityDescriptorForNamedPipeInstance(&created_len);
  ASSERT_EQ(created_len, sec_desc_len);
  EXPECT_EQ(memcmp(sec_desc, created, sec_desc_len), 0);
}

}  // namespace
}  // namespace test
}  // namespace crashpad
