// Copyright 2019 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 "kerberos/config_parser.h"

#include <vector>

#include <base/containers/contains.h>
#include <base/strings/string_split.h>

namespace kerberos {
namespace {

// Maximum depth of nested '{' in the config.
constexpr int kMaxGroupLevelDepth = 1000;

// See
// https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html
// for a description of the krb5.conf format.

// Directives that are not relations (i.e. key=value). All blacklisted.
const char* const kDirectives[] = {"module", "include", "includedir"};

// Whitelisted configuration keys in the [libdefaults] section.
const char* const kLibDefaultsWhitelist[] = {
    "canonicalize",
    "clockskew",
    "default_tgs_enctypes",
    "default_tkt_enctypes",
    "dns_canonicalize_hostname",
    "dns_lookup_kdc",
    "extra_addresses",
    "forwardable",
    "ignore_acceptor_hostname",
    "kdc_default_options",
    "kdc_timesync",
    "noaddresses",
    "permitted_enctypes",
    "preferred_preauth_types",
    "proxiable",
    "rdns",
    "renew_lifetime",
    "ticket_lifetime",
    "udp_preference_limit",
};

// Whitelisted configuration keys in the [realms] section.
const char* const kRealmsWhitelist[] = {
    "admin_server", "auth_to_local", "kdc", "kpasswd_server", "master_kdc",
};

// Whitelisted sections. Any key in "domain_realm" and "capaths" is accepted.
constexpr char kSectionLibdefaults[] = "libdefaults";
constexpr char kSectionRealms[] = "realms";
constexpr char kSectionDomainRealm[] = "domain_realm";
constexpr char kSectionCapaths[] = "capaths";

const char* const kSectionWhitelist[] = {kSectionLibdefaults, kSectionRealms,
                                         kSectionDomainRealm, kSectionCapaths};

// List of encryption types fields allowed inside [libdefaults] section.
const char* const kEnctypesFields[] = {
    "default_tgs_enctypes",
    "default_tkt_enctypes",
    "permitted_enctypes",
};

// List of weak encryption types. |DEFAULT| value is also listed because it
// includes both weak and strong types.
const char* const kWeakEnctypes[] = {
    "DEFAULT",
    "des",
    "des3",
    "rc4",
    "des-cbc-crc",
    "des-cbc-md4",
    "des-cbc-md5",
    "des-cbc-raw",
    "des-hmac-sha1",
    "des3-cbc-raw",
    "des3-cbc-sha1",
    "des3-hmac-sha1",
    "des3-cbc-sha1-kd",
    "arcfour-hmac",
    "rc4-hmac",
    "arcfour-hmac-md5",
    "arcfour-hmac-exp",
    "rc4-hmac-exp",
    "arcfour-hmac-md5-exp",
};

// List of strong encryption types. |DEFAULT| value is also listed because it
// includes both weak and strong types.
const char* const kStrongEnctypes[] = {
    "DEFAULT",    "aes",     "aes256-cts-hmac-sha1-96",
    "aes256-cts", "AES-256", "aes128-cts-hmac-sha1-96",
    "aes128-cts", "AES-128",
};

ConfigErrorInfo MakeErrorInfo(ConfigErrorCode code, int line_index) {
  ConfigErrorInfo error_info;
  error_info.set_code(code);
  error_info.set_line_index(line_index);
  return error_info;
}

}  // namespace

ConfigParser::ConfigParser()
    : libdefaults_whitelist_(std::begin(kLibDefaultsWhitelist),
                             std::end(kLibDefaultsWhitelist)),
      realms_whitelist_(std::begin(kRealmsWhitelist),
                        std::end(kRealmsWhitelist)),
      section_whitelist_(std::begin(kSectionWhitelist),
                         std::end(kSectionWhitelist)),
      enctypes_fields_(std::begin(kEnctypesFields), std::end(kEnctypesFields)),
      weak_enctypes_(std::begin(kWeakEnctypes), std::end(kWeakEnctypes)),
      strong_enctypes_(std::begin(kStrongEnctypes), std::end(kStrongEnctypes)) {
}

ConfigErrorInfo ConfigParser::Validate(const std::string& krb5conf) const {
  KerberosEncryptionTypes encryption_types;
  return ParseConfig(krb5conf, &encryption_types);
}

bool ConfigParser::GetEncryptionTypes(
    const std::string& krb5conf,
    KerberosEncryptionTypes* encryption_types) const {
  ConfigErrorInfo error_info = ParseConfig(krb5conf, encryption_types);
  return error_info.code() == CONFIG_ERROR_NONE;
}

// Validates the config and gets encryption types from it. Finds the enctypes
// fields and maps the union of the enctypes into one of the buckets of
// interest: 'All', 'Strong' or 'Legacy'. If an enctypes field is missing, the
// default value for this field ('All') will be used.
ConfigErrorInfo ConfigParser::ParseConfig(
    const std::string& krb5conf,
    KerberosEncryptionTypes* encryption_types) const {
  // Variables used to keep track of encryption fields and types on |krc5conf|.
  StringSet listed_enctypes_fields;
  bool has_weak_enctype = false;
  bool has_strong_enctype = false;

  // Initializes |encryption_types| with the default value in our feature. It
  // will be replaced at the end of this method, if |krb5conf| is valid.
  *encryption_types = KerberosEncryptionTypes::kStrong;

  // Keep empty lines, they're necessary to get the line numbers right.
  // Note: The MIT krb5 parser does not count \r as newline.
  const std::vector<std::string> lines = base::SplitString(
      krb5conf, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  // Level of nested curly braces {}.
  int group_level = 0;

  // Opening curly braces '{' can be on the same line and on the next line. This
  // is set to true if a '{' is expected on the next line.
  bool expect_opening_curly_brace = false;

  // Current [section].
  std::string current_section;

  for (size_t line_index = 0; line_index < lines.size(); ++line_index) {
    // Convert to c_str() and back to get rid of embedded \0's.
    std::string line = lines.at(line_index).c_str();

    // Are we expecting a '{' to open a { group }?
    if (expect_opening_curly_brace) {
      if (line.empty() || line.at(0) != '{') {
        return MakeErrorInfo(CONFIG_ERROR_EXPECTED_OPENING_CURLY_BRACE,
                             line_index);
      }
      group_level++;
      // If too nested config, exit here to prevent krb5 stack overflow.
      if (group_level > kMaxGroupLevelDepth)
        return MakeErrorInfo(CONFIG_ERROR_TOO_MANY_NESTED_GROUPS, line_index);
      expect_opening_curly_brace = false;
      continue;
    }

    // Skip empty lines.
    if (line.empty())
      continue;

    // Skip comments.
    if (line.at(0) == ';' || line.at(0) == '#')
      continue;

    // Bail on any |kDirectives|.
    for (const char* directive : kDirectives) {
      const int len = strlen(directive);
      const int line_len = static_cast<int>(line.size());
      if (strncmp(line.c_str(), directive, len) == 0 &&
          (len >= line_len || isspace(line.at(len)))) {
        return MakeErrorInfo(CONFIG_ERROR_KEY_NOT_SUPPORTED, line_index);
      }
    }

    // Check for '}' to close a { group }.
    if (line.at(0) == '}') {
      if (group_level == 0)
        return MakeErrorInfo(CONFIG_ERROR_EXTRA_CURLY_BRACE, line_index);
      group_level--;
      continue;
    }

    // Check for new [section].
    if (line.at(0) == '[') {
      // Bail if section is within a { group }.
      if (group_level > 0)
        return MakeErrorInfo(CONFIG_ERROR_SECTION_NESTED_IN_GROUP, line_index);

      // Bail if closing bracket is missing or if there's more stuff after the
      // closing bracket (the final marker '*' is fine).
      std::vector<std::string> parts = base::SplitString(
          line, "]", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
      if (parts.size() != 2 || !(parts.at(1).empty() || parts.at(1) == "*"))
        return MakeErrorInfo(CONFIG_ERROR_SECTION_SYNTAX, line_index);

      current_section = parts.at(0).substr(1);

      // Bail if the section is not supported, e.g. [appdefaults].
      if (current_section.empty() ||
          !base::Contains(section_whitelist_, current_section)) {
        return MakeErrorInfo(CONFIG_ERROR_SECTION_NOT_SUPPORTED, line_index);
      }
      continue;
    }

    // Check for "key = value" or "key = {".
    std::vector<std::string> parts = base::SplitString(
        line, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

    // Remove final marker.
    std::string& key = parts.at(0);
    if (key.back() == '*')
      key.pop_back();

    // No space allowed in the key.
    if (std::find_if(key.begin(), key.end(), isspace) != key.end())
      return MakeErrorInfo(CONFIG_ERROR_RELATION_SYNTAX, line_index);

    // Final marker must come immediately after key.
    if (key.empty() || isspace(key.back()))
      return MakeErrorInfo(CONFIG_ERROR_RELATION_SYNTAX, line_index);

    // Is there at least one '=' sign?
    if (parts.size() < 2)
      return MakeErrorInfo(CONFIG_ERROR_RELATION_SYNTAX, line_index);

    const std::string& value = parts.at(1);
    if (parts.size() == 2) {
      // Check for a '{' to start a group. The '{' could also be on the next
      // line. If there's anything except whitespace after '{', it counts as
      // value, not as a group.
      // Note: If there is more than one '=', it cannot be the start of a group,
      // e.g. key==\n{.
      if (value.empty()) {
        expect_opening_curly_brace = true;
        continue;
      }
      if (value == "{") {
        group_level++;
        // If too nested config, exit here to prevent krb5 stack overflow.
        if (group_level > kMaxGroupLevelDepth)
          return MakeErrorInfo(CONFIG_ERROR_TOO_MANY_NESTED_GROUPS, line_index);
        continue;
      }
    }

    // Check whether we support the key.
    if (!IsKeySupported(key, current_section, group_level))
      return MakeErrorInfo(CONFIG_ERROR_KEY_NOT_SUPPORTED, line_index);

    // If |key| is a enctypes field in the [libdefaults] section.
    if (current_section == kSectionLibdefaults && group_level <= 1 &&
        base::Contains(enctypes_fields_, key)) {
      listed_enctypes_fields.insert(key);

      // Note: encryption types can be delimited by comma or whitespace.
      const std::vector<std::string> enctypes = base::SplitString(
          value, ", ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

      for (const std::string& type : enctypes) {
        has_weak_enctype |= base::Contains(weak_enctypes_, type);
        has_strong_enctype |= base::Contains(strong_enctypes_, type);
      }
    }
  }

  // Note: if an enctypes field is missing, the default value is 'All'.
  if (listed_enctypes_fields.size() < enctypes_fields_.size() ||
      (has_weak_enctype && has_strong_enctype)) {
    *encryption_types = KerberosEncryptionTypes::kAll;
  } else if (has_strong_enctype) {
    *encryption_types = KerberosEncryptionTypes::kStrong;
  } else {
    *encryption_types = KerberosEncryptionTypes::kLegacy;
  }

  ConfigErrorInfo error_info;
  error_info.set_code(CONFIG_ERROR_NONE);
  return error_info;
}

bool ConfigParser::IsKeySupported(const std::string& key,
                                  const std::string& section,
                                  int group_level) const {
  // Bail on anything outside of a section.
  if (section.empty())
    return false;

  // Enforce only whitelisted libdefaults keys on the root and realm levels:
  // [libdefaults]
  //   clockskew = 300
  //   EXAMPLE.COM = {
  //     clockskew = 500
  //   }
  if (section == kSectionLibdefaults && group_level <= 1) {
    return base::Contains(libdefaults_whitelist_, key);
  }

  // Enforce only whitelisted realm keys on the root and realm levels:
  // [realms]
  //   kdc = kerberos1.example.com
  //   EXAMPLE.COM = {
  //      kdc = kerberos2.example.com
  //   }
  // Not sure if they can actually be at the root level, but just in case...
  if (section == kSectionRealms && group_level <= 1)
    return base::Contains(realms_whitelist_, key);

  // Anything else is fine (all keys of other supported sections).
  return true;
}

}  // namespace kerberos
