// Copyright (c) 2013 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 "chrome/browser/policy/preg_parser_win.h"

#include <windows.h>

#include <algorithm>
#include <iterator>
#include <vector>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
#include "base/values.h"
#include "chrome/browser/policy/policy_load_status.h"
#include "chrome/browser/policy/registry_dict_win.h"

namespace policy {
namespace preg_parser {

const char kPRegFileHeader[8] =
    { 'P', 'R', 'e', 'g', '\x01', '\x00', '\x00', '\x00' };

// Maximum PReg file size we're willing to accept.
const int64 kMaxPRegFileSize = 1024 * 1024 * 16;

// Constants for PReg file delimiters.
const char16 kDelimBracketOpen = L'[';
const char16 kDelimBracketClose = L']';
const char16 kDelimSemicolon = L';';

// Registry path separator.
const char16 kRegistryPathSeparator[] = L"\\";

// Magic strings for the PReg value field to trigger special actions.
const char kActionTriggerPrefix[] = "**";
const char kActionTriggerDeleteValues[] = "deletevalues";
const char kActionTriggerDel[] = "del.";
const char kActionTriggerDelVals[] = "delvals";
const char kActionTriggerDeleteKeys[] = "deletekeys";
const char kActionTriggerSecureKey[] = "securekey";
const char kActionTriggerSoft[] = "soft";

// Returns the character at |cursor| and increments it, unless the end is here
// in which case -1 is returned.
int NextChar(const uint8** cursor, const uint8* end) {
  // Only read the character if a full char16 is available.
  if (*cursor + sizeof(char16) > end)
    return -1;

  int result = **cursor | (*(*cursor + 1) << 8);
  *cursor += sizeof(char16);
  return result;
}

// Reads a fixed-size field from a PReg file.
bool ReadFieldBinary(const uint8** cursor,
                     const uint8* end,
                     int size,
                     uint8* data) {
  if (!size)
    return false;
  const uint8* field_end = *cursor + size;
  if (field_end > end)
    return false;
  std::copy(*cursor, field_end, data);
  *cursor = field_end;
  return true;
}

bool ReadField32(const uint8** cursor, const uint8* end, uint32* data) {
  uint32 value = 0;
  if (!ReadFieldBinary(cursor, end, sizeof(uint32),
                       reinterpret_cast<uint8*>(&value))) {
    return false;
  }
  *data = base::ByteSwapToLE32(value);
  return true;
}

// Reads a string field from a  file.
bool ReadFieldString(const uint8** cursor, const uint8* end, string16* str) {
  int current = -1;
  while ((current = NextChar(cursor, end)) > 0x0000)
    *str += current;

  return current == L'\0';
}

std::string DecodePRegStringValue(const std::vector<uint8>& data) {
  size_t len = data.size() / sizeof(char16);
  if (len <= 0)
    return std::string();

  const char16* chars = reinterpret_cast<const char16*>(vector_as_array(&data));
  string16 result;
  std::transform(chars, chars + len - 1, std::back_inserter(result),
                 std::ptr_fun(base::ByteSwapToLE16));
  return UTF16ToUTF8(result);
}

// Decodes a value from a PReg file given as a uint8 vector.
bool DecodePRegValue(uint32 type,
                     const std::vector<uint8>& data,
                     scoped_ptr<base::Value>* value) {
  switch (type) {
    case REG_SZ:
    case REG_EXPAND_SZ:
      value->reset(base::Value::CreateStringValue(DecodePRegStringValue(data)));
      return true;
    case REG_DWORD_LITTLE_ENDIAN:
    case REG_DWORD_BIG_ENDIAN:
      if (data.size() == sizeof(uint32)) {
        uint32 val = *reinterpret_cast<const uint32*>(vector_as_array(&data));
        if (type == REG_DWORD_BIG_ENDIAN)
          val = base::NetToHost32(val);
        else
          val = base::ByteSwapToLE32(val);
        value->reset(base::Value::CreateIntegerValue(static_cast<int>(val)));
        return true;
      } else {
        LOG(ERROR) << "Bad data size " << data.size();
      }
      break;
    case REG_NONE:
    case REG_LINK:
    case REG_MULTI_SZ:
    case REG_RESOURCE_LIST:
    case REG_FULL_RESOURCE_DESCRIPTOR:
    case REG_RESOURCE_REQUIREMENTS_LIST:
    case REG_QWORD_LITTLE_ENDIAN:
    default:
      LOG(ERROR) << "Unsupported registry data type " << type;
  }

  return false;
}

// Adds the record data passed via parameters to |dict| in case the data is
// relevant policy for Chromium.
void HandleRecord(const string16& key_name,
                  const string16& value,
                  uint32 type,
                  const std::vector<uint8>& data,
                  RegistryDict* dict) {
  // Locate/create the dictionary to place the value in.
  std::vector<string16> path;

  Tokenize(key_name, kRegistryPathSeparator, &path);
  for (std::vector<string16>::const_iterator entry(path.begin());
       entry != path.end(); ++entry) {
    if (entry->empty())
      continue;
    const std::string name = UTF16ToUTF8(*entry);
    RegistryDict* subdict = dict->GetKey(name);
    if (!subdict) {
      subdict = new RegistryDict();
      dict->SetKey(name, make_scoped_ptr(subdict));
    }
    dict = subdict;
  }

  if (value.empty())
    return;

  std::string value_name(UTF16ToUTF8(value));
  if (!StartsWithASCII(value_name, kActionTriggerPrefix, true)) {
    scoped_ptr<base::Value> value;
    if (DecodePRegValue(type, data, &value))
      dict->SetValue(value_name, value.Pass());
    return;
  }

  std::string action_trigger(StringToLowerASCII(value_name.substr(
      arraysize(kActionTriggerPrefix) - 1)));
  if (action_trigger == kActionTriggerDeleteValues) {
    std::vector<std::string> values;
    Tokenize(DecodePRegStringValue(data), ";", &values);
    for (std::vector<std::string>::const_iterator value(values.begin());
         value != values.end(); ++value) {
      dict->RemoveValue(*value);
    }
  } else if (StartsWithASCII(action_trigger, kActionTriggerDeleteKeys, true)) {
    std::vector<std::string> keys;
    Tokenize(DecodePRegStringValue(data), ";", &keys);
    for (std::vector<std::string>::const_iterator key(keys.begin());
         key != keys.end(); ++key) {
      dict->RemoveKey(*key);
    }
  } else if (StartsWithASCII(action_trigger, kActionTriggerDel, true)) {
    dict->RemoveValue(
        value_name.substr(arraysize(kActionTriggerPrefix) - 1 +
                          arraysize(kActionTriggerDel) - 1));
  } else if (StartsWithASCII(action_trigger, kActionTriggerDelVals, true)) {
    // Delete all values.
    dict->ClearValues();
  } else if (StartsWithASCII(action_trigger, kActionTriggerSecureKey, true) ||
             StartsWithASCII(action_trigger, kActionTriggerSoft, true)) {
    // Doesn't affect values.
  } else {
    LOG(ERROR) << "Bad action trigger " << value_name;
  }
}

bool ReadFile(const base::FilePath& file_path,
              const string16& root,
              RegistryDict* dict,
              PolicyLoadStatusSample* status) {
  base::MemoryMappedFile mapped_file;
  if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) {
    PLOG(ERROR) << "Failed to map " << file_path.value();
    status->Add(POLICY_LOAD_STATUS_READ_ERROR);
    return false;
  }

  if (mapped_file.length() > kMaxPRegFileSize) {
    LOG(ERROR) << "PReg file " << file_path.value() << " too large: "
               << mapped_file.length();
    status->Add(POLICY_LOAD_STATUS_TOO_BIG);
    return false;
  }

  // Check the header.
  const int kHeaderSize = arraysize(kPRegFileHeader);
  if (mapped_file.length() < kHeaderSize ||
      memcmp(kPRegFileHeader, mapped_file.data(), kHeaderSize) != 0) {
    LOG(ERROR) << "Bad policy file " << file_path.value();
    status->Add(POLICY_LOAD_STATUS_PARSE_ERROR);
    return false;
  }

  // Parse file contents, which is UCS-2 and little-endian. The latter I
  // couldn't find documentation on, but the example I saw were all
  // little-endian. It'd be interesting to check on big-endian hardware.
  const uint8* cursor = mapped_file.data() + kHeaderSize;
  const uint8* end = mapped_file.data() + mapped_file.length();
  while (true) {
    if (cursor == end)
      return true;

    if (NextChar(&cursor, end) != kDelimBracketOpen)
      break;

    // Read the record fields.
    string16 key_name;
    string16 value;
    uint32 type = 0;
    uint32 size = 0;
    std::vector<uint8> data;

    if (!ReadFieldString(&cursor, end, &key_name))
      break;

    int current = NextChar(&cursor, end);
    if (current == kDelimSemicolon) {
      if (!ReadFieldString(&cursor, end, &value))
        break;
      current = NextChar(&cursor, end);
    }

    if (current == kDelimSemicolon) {
      if (!ReadField32(&cursor, end, &type))
        break;
      current = NextChar(&cursor, end);
    }

    if (current == kDelimSemicolon) {
      if (!ReadField32(&cursor, end, &size))
        break;
      current = NextChar(&cursor, end);
    }

    if (current == kDelimSemicolon) {
      if (size > kMaxPRegFileSize)
        break;
      data.resize(size);
      if (!ReadFieldBinary(&cursor, end, size, vector_as_array(&data)))
        break;
      current = NextChar(&cursor, end);
    }

    if (current != kDelimBracketClose)
      break;

    // Process the record if it is within the |root| subtree.
    if (StartsWith(key_name, root, false))
      HandleRecord(key_name.substr(root.size()), value, type, data, dict);
  }

  LOG(ERROR) << "Error parsing " << file_path.value() << " at offset "
             << reinterpret_cast<const uint8*>(cursor - 1) - mapped_file.data();
  status->Add(POLICY_LOAD_STATUS_PARSE_ERROR);
  return false;
}

}  // namespace preg_parser
}  // namespace policy
