// 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/stl_util.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
