// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "kudu/security/init.h"

#include <krb5/krb5.h>

#include <algorithm>
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <memory>
#include <mutex>
#include <optional>
#include <ostream>
#include <random>
#include <string>

#include <gflags/gflags.h>
#include <glog/logging.h>

#include "kudu/gutil/macros.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/strings/util.h"
#include "kudu/security/kinit_context.h"
#include "kudu/util/countdown_latch.h"
#include "kudu/util/flag_tags.h"
#include "kudu/util/monotime.h"
#include "kudu/util/net/net_util.h"
#include "kudu/util/rw_mutex.h"
#include "kudu/util/scoped_cleanup.h"
#include "kudu/util/status.h"
#include "kudu/util/thread.h"

#if defined(__APPLE__)
// Almost all functions in the krb5 API are marked as deprecated in favor
// of GSS.framework in macOS.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif // #if defined(__APPLE__)

#ifndef __APPLE__
static constexpr bool kDefaultSystemAuthToLocal = true;
#else
// macOS's Heimdal library has a no-op implementation of
// krb5_aname_to_localname, so instead we just use the simple
// implementation.
static constexpr bool kDefaultSystemAuthToLocal = false;
#endif

DEFINE_bool(use_system_auth_to_local, kDefaultSystemAuthToLocal,
            "When enabled, use the system krb5 library to map Kerberos principal "
            "names to local (short) usernames. If not enabled, the first component "
            "of the principal will be used as the short name. For example, "
            "'kudu/foo.example.com@EXAMPLE' will map to 'kudu'.");
TAG_FLAG(use_system_auth_to_local, advanced);

DEFINE_string(principal, "kudu/_HOST",
              "Kerberos principal that this daemon will log in as. The special token "
              "_HOST will be replaced with the FQDN of the local host.");
TAG_FLAG(principal, advanced);
TAG_FLAG(principal, stable);

DEFINE_string(keytab_file, "",
              "Path to the Kerberos Keytab file for this server. Specifying a "
              "keytab file will cause the server to kinit, and enable Kerberos "
              "to be used to authenticate RPC connections.");
TAG_FLAG(keytab_file, stable);

using std::mt19937;
using std::nullopt;
using std::optional;
using std::random_device;
using std::string;
using std::uniform_int_distribution;
using std::uniform_real_distribution;
using strings::Substitute;

namespace kudu {
namespace security {

// Global instance of the context used by the kinit/reacquire thread.
KinitContext* g_kinit_ctx = nullptr;

namespace {

// Global context for usage of the Krb5 library.
krb5_context g_krb5_ctx;

// This lock is used to avoid a race while reacquiring the kerberos ticket.
// The race can occur between the time we reinitialize the cache and the
// time when we actually store the new credentials back in the cache.
RWMutex* g_kerberos_reinit_lock;

Status Krb5CallToStatus(krb5_context ctx, krb5_error_code code) {
  if (code == 0) return Status::OK();

  std::unique_ptr<const char, std::function<void(const char*)>> err_msg(
      krb5_get_error_message(ctx, code),
      [ctx](const char* msg) { krb5_free_error_message(ctx, msg); });
  return Status::RuntimeError(err_msg.get());
}
#define KRB5_RETURN_NOT_OK_PREPEND(call, prepend) \
  RETURN_NOT_OK_PREPEND(Krb5CallToStatus(g_krb5_ctx, (call)), (prepend))


void InitKrb5Ctx() {
  static std::once_flag once;
  std::call_once(once, [&]() {
      CHECK_EQ(krb5_init_context(&g_krb5_ctx), 0);
      // Work around the lack of thread safety in krb5_parse_name() by implicitly
      // initializing g_krb5_ctx->default_realm once. The assumption is that this
      // function is called once in a single thread environment during initialization.
      //
      // TODO(KUDU-2706): Fix unsafe sharing of 'g_krb5_ctx'.
      // According to Kerberos documentation
      // (https://github.com/krb5/krb5/blob/master/doc/threads.txt), any use of
      // krb5_context must be confined to one thread at a time by the application code.
      // The current way of sharing of 'g_krb5_ctx' between threads is actually unsafe.
      char* unused_realm;
      CHECK_EQ(krb5_get_default_realm(g_krb5_ctx, &unused_realm), 0);
      krb5_free_default_realm(g_krb5_ctx, unused_realm);

      g_kerberos_reinit_lock = new RWMutex(RWMutex::Priority::PREFER_WRITING);
    });
}

// Port of the data_eq() implementation from krb5/k5-int.h
inline int data_eq(krb5_data d1, krb5_data d2) {
    return (d1.length == d2.length && !memcmp(d1.data, d2.data, d1.length));
}

// Port of the data_eq_string() implementation from krb5/k5-int.h
inline int data_eq_string(krb5_data d, const char *s) {
    return (d.length == strlen(s) && !memcmp(d.data, s, d.length));
}

Status Krb5UnparseName(krb5_principal princ, string* name) {
  char* c_name;
  KRB5_RETURN_NOT_OK_PREPEND(krb5_unparse_name(g_krb5_ctx, princ, &c_name),
                             "krb5_unparse_name");
  SCOPED_CLEANUP({
      krb5_free_unparsed_name(g_krb5_ctx, c_name);
    });
  *name = c_name;
  return Status::OK();
}

} // anonymous namespace

KinitContext::KinitContext() : stop_latch_(1) {}

KinitContext::~KinitContext() {
  // Free memory associated with these objects.
  Kdestroy();
  if (principal_ != nullptr) krb5_free_principal(g_krb5_ctx, principal_);
  if (keytab_ != nullptr) krb5_kt_close(g_krb5_ctx, keytab_);
  if (ccache_ != nullptr) krb5_cc_close(g_krb5_ctx, ccache_);
  if (opts_ != nullptr) krb5_get_init_creds_opt_free(g_krb5_ctx, opts_);
}

int32_t KinitContext::GetNextRenewInterval(uint32_t num_retries) {
  int32_t time_remaining = ticket_end_timestamp_ - time(nullptr);

  // If the last ticket reacqusition was a failure, we back off our retry attempts exponentially.
  if (num_retries > 0) return GetBackedOffRenewInterval(time_remaining, num_retries);

  // If the time remaining between now and ticket expiry is:
  // * > 10 minutes:   We attempt to reacquire the ticket between 5 seconds and 5 minutes before the
  //                   ticket expires.
  // * 5 - 10 minutes: We attempt to reacquire the ticket betwen 5 seconds and 1 minute before the
  //                   ticket expires.
  // * < 5 minutes:    Attempt to reacquire the ticket every 'time_remaining'.
  // The jitter is added to make sure that every server doesn't flood the KDC at the same time.
  random_device rd;
  mt19937 generator(rd());
  if (time_remaining > 600) {
    uniform_int_distribution<> dist(5, 300);
    return time_remaining - dist(generator);
  } else if (time_remaining > 300) {
    uniform_int_distribution<> dist(5, 60);
    return time_remaining - dist(generator);
  }
  return time_remaining;
}

int32_t KinitContext::GetBackedOffRenewInterval(int32_t time_remaining, uint32_t num_retries) {
  // The minimum sleep interval after a failure will be 60 seconds.
  int32_t next_interval = std::max(time_remaining, 60);
  // Don't back off more than 30 minutes.
  int32_t base_time = std::min(next_interval * (1 << num_retries), 1800);
  random_device rd;
  mt19937 generator(rd());
  uniform_real_distribution<> dist(0.5, 1.5);
  return static_cast<int32_t>(base_time * dist(generator));
}

Status KinitContext::DoRenewal() {
  bool found_in_cache;
  RETURN_NOT_OK(DoRenewalInternal(&found_in_cache));
  if (!found_in_cache) {
    // Cache appears to be corrupted somehow - redo the kinit and retry.
    RETURN_NOT_OK_PREPEND(KinitInternal(), "redoing kinit after error");
    RETURN_NOT_OK(DoRenewalInternal(&found_in_cache));
    if (!found_in_cache) {
      return Status::RuntimeError("Could not find TGT in cache after kinit");
    }
  }
  return Status::OK();
}

Status KinitContext::DoRenewalInternal(bool* found_in_cache) {
  *found_in_cache = false;
  krb5_cc_cursor cursor;
  // Setup a cursor to iterate through the credential cache.
  Status status =
      Krb5CallToStatus(g_krb5_ctx, krb5_cc_start_seq_get(g_krb5_ctx, ccache_, &cursor));
  if (!status.ok()) {
    LOG(WARNING) << Substitute("Error while opening credential cache '$0' of type $1: $2",
        krb5_cc_get_name(g_krb5_ctx, ccache_), krb5_cc_get_type(g_krb5_ctx, ccache_),
        status.ToString());
    return Status::OK();
  }
  SCOPED_CLEANUP({
      krb5_cc_end_seq_get(g_krb5_ctx, ccache_, &cursor); });

  krb5_creds creds;
  memset(&creds, 0, sizeof(krb5_creds));

  krb5_error_code rc;
  // Iterate through the credential cache.
  while (!(rc = krb5_cc_next_cred(g_krb5_ctx, ccache_, &cursor, &creds))) {
    SCOPED_CLEANUP({
        krb5_free_cred_contents(g_krb5_ctx, &creds); });
    if (krb5_is_config_principal(g_krb5_ctx, creds.server)) continue;

    // We only want to reacquire the TGT (Ticket Granting Ticket). Ignore all other tickets.
    // This follows the same format as is_local_tgt() from krb5:src/clients/klist/klist.c
    if (creds.server->length != 2 ||
        data_eq(creds.server->data[1], principal_->realm) == 0 ||
        data_eq_string(creds.server->data[0], KRB5_TGS_NAME) == 0 ||
        data_eq(creds.server->realm, principal_->realm) == 0) {
      continue;
    }
    *found_in_cache = true;

    krb5_creds new_creds;
    memset(&new_creds, 0, sizeof(krb5_creds));
    SCOPED_CLEANUP({
        krb5_free_cred_contents(g_krb5_ctx, &new_creds); });
    // Acquire a new ticket using the keytab. This ticket will automatically be put into the
    // credential cache.
    {
      std::lock_guard<RWMutex> l(*g_kerberos_reinit_lock);
      KRB5_RETURN_NOT_OK_PREPEND(krb5_get_init_creds_keytab(g_krb5_ctx, &new_creds, principal_,
                                                            keytab_, 0 /* valid from now */,
                                                            nullptr /* TKT service name */,
                                                            opts_),
                                 "Reacquire error: unable to login from keytab");
#if !defined(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_OUT_CCACHE)
      // Heimdal krb5 doesn't have the 'krb5_get_init_creds_opt_set_out_ccache' option,
      // so use this alternate route.
      KRB5_RETURN_NOT_OK_PREPEND(krb5_cc_initialize(g_krb5_ctx, ccache_, principal_),
                                 "Reacquire error: could not init ccache");

      KRB5_RETURN_NOT_OK_PREPEND(krb5_cc_store_cred(g_krb5_ctx, ccache_, &new_creds),
                                 "Reacquire error: could not store creds in cache");
#endif
    }
    LOG(INFO) << "Successfully reacquired a new kerberos TGT";
    ticket_end_timestamp_ = new_creds.times.endtime;
    break;
  }
  if (!*found_in_cache) {
    LOG(WARNING) << Substitute(
        "Could not find kerberos principal in credential cache '$0' of type $1",
        krb5_cc_get_name(g_krb5_ctx, ccache_), krb5_cc_get_type(g_krb5_ctx, ccache_));
  }
  return Status::OK();
}

Status KinitContext::Kinit(const string& keytab_path, const string& principal) {
  InitKrb5Ctx();

  // Parse the principal
  KRB5_RETURN_NOT_OK_PREPEND(krb5_parse_name(g_krb5_ctx, principal.c_str(), &principal_),
                             "could not parse principal");

  KRB5_RETURN_NOT_OK_PREPEND(krb5_kt_resolve(g_krb5_ctx, keytab_path.c_str(), &keytab_),
                             "unable to resolve keytab");

  KRB5_RETURN_NOT_OK_PREPEND(krb5_cc_default(g_krb5_ctx, &ccache_),
                             "unable to get default credentials cache");

  KRB5_RETURN_NOT_OK_PREPEND(krb5_get_init_creds_opt_alloc(g_krb5_ctx, &opts_),
                             "unable to allocate get_init_creds_opt struct");
  RETURN_NOT_OK(KinitInternal());

  // Start the thread to renew and reacquire Kerberos tickets.
  RETURN_NOT_OK(Thread::Create("kerberos", "reacquire thread",
                               [this]() { this->RenewThread(); }, &reacquire_thread_));
  return Status::OK();
}

void KinitContext::Kdestroy() {
  stop_latch_.CountDown();
  if (reacquire_thread_.get() != nullptr) {
    reacquire_thread_->Join();
  }
}

Status KinitContext::KinitInternal() {
#if defined(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_OUT_CCACHE)
  KRB5_RETURN_NOT_OK_PREPEND(krb5_get_init_creds_opt_set_out_ccache(g_krb5_ctx, opts_, ccache_),
                             "unable to set init_creds options");
#endif

  krb5_creds creds;
  KRB5_RETURN_NOT_OK_PREPEND(krb5_get_init_creds_keytab(g_krb5_ctx, &creds, principal_, keytab_,
                                                        0 /* valid from now */,
                                                        nullptr /* TKT service name */, opts_),
                             "unable to login from keytab");
  SCOPED_CLEANUP({
      krb5_free_cred_contents(g_krb5_ctx, &creds); });

  ticket_end_timestamp_ = creds.times.endtime;

#if !defined(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_OUT_CCACHE)
  // Heimdal krb5 doesn't have the 'krb5_get_init_creds_opt_set_out_ccache' option,
  // so use this alternate route.
  KRB5_RETURN_NOT_OK_PREPEND(krb5_cc_initialize(g_krb5_ctx, ccache_, principal_),
                             "could not init ccache");

  KRB5_RETURN_NOT_OK_PREPEND(krb5_cc_store_cred(g_krb5_ctx, ccache_, &creds),
                             "could not store creds in cache");
#endif

  // Convert the logged-in principal back to a string. This may be different than
  // 'principal', since the default realm will be filled in based on the Kerberos
  // configuration if not originally specified.
  RETURN_NOT_OK_PREPEND(Krb5UnparseName(principal_, &principal_str_),
                        "could not stringify the logged-in principal");
  RETURN_NOT_OK_PREPEND(MapPrincipalToLocalName(principal_str_, &username_str_),
                        "could not map own logged-in principal to a short username");

  LOG(INFO) << "Logged in from keytab as " << principal_str_
            << " (short username " << username_str_ << ")";

  return Status::OK();
}

// Periodically calls DoRenewal().
void KinitContext::RenewThread() {
  uint32_t failure_retries = 0;
  int64_t renew_interval_s = GetNextRenewInterval(failure_retries);
  while (!stop_latch_.WaitFor(MonoDelta::FromSeconds(renew_interval_s))) {
    Status s = DoRenewal();
    WARN_NOT_OK(s, "Kerberos reacquire error: ");
    if (!s.ok()) {
      ++failure_retries;
    } else {
      failure_retries = 0;
    }

    if (failure_retries > 0) {
      // Log in the abnormal case where something failed.
      LOG(INFO) << Substitute("Renew thread sleeping after $0 failures for $1s",
          failure_retries, renew_interval_s);
    }

    // This thread is run immediately after the first Kinit, so sleep first.
    renew_interval_s = GetNextRenewInterval(failure_retries);
  }
}

RWMutex* KerberosReinitLock() {
  return g_kerberos_reinit_lock;
}

Status CanonicalizeKrb5Principal(std::string* principal) {
  InitKrb5Ctx();
  krb5_principal princ;
  KRB5_RETURN_NOT_OK_PREPEND(krb5_parse_name(g_krb5_ctx, principal->c_str(), &princ),
                             "could not parse principal");
  SCOPED_CLEANUP({
      krb5_free_principal(g_krb5_ctx, princ);
    });
  RETURN_NOT_OK_PREPEND(Krb5UnparseName(princ, principal),
                        "failed to convert principal back to string");
  return Status::OK();
}

Status MapPrincipalToLocalName(const std::string& principal, std::string* local_name) {
  InitKrb5Ctx();
  krb5_principal princ;
  KRB5_RETURN_NOT_OK_PREPEND(krb5_parse_name(g_krb5_ctx, principal.c_str(), &princ),
                             "could not parse principal");
  SCOPED_CLEANUP({
      krb5_free_principal(g_krb5_ctx, princ);
    });
  char buf[1024];
  krb5_error_code rc = KRB5_LNAME_NOTRANS;
  if (FLAGS_use_system_auth_to_local) {
    rc = krb5_aname_to_localname(g_krb5_ctx, princ, arraysize(buf), buf);
  }
  if (rc == KRB5_LNAME_NOTRANS || rc == KRB5_PLUGIN_NO_HANDLE) {
    // No name mapping specified, or krb5-based name mapping is disabled.
    //
    // We fall back to simply taking the first component of the principal, for
    // compatibility with the default behavior of Hadoop.
    //
    // NOTE: KRB5_PLUGIN_NO_HANDLE isn't typically expected here, but works around
    // a bug in SSSD's auth_to_local implementation: https://pagure.io/SSSD/sssd/issue/3459
    //
    // TODO(todd): we should support custom configured auth-to-local mapping, since
    // most Hadoop ecosystem components do not load them from krb5.conf.
    if (princ->length > 0) {
      local_name->assign(princ->data[0].data, princ->data[0].length);
      return Status::OK();
    }
    return Status::NotFound("unable to find first component of principal");
  }
  if (rc == KRB5_CONFIG_NOTENUFSPACE) {
    return Status::InvalidArgument("mapped username too large");
  }
  KRB5_RETURN_NOT_OK_PREPEND(rc, "krb5_aname_to_localname");
  if (strlen(buf) == 0) {
    return Status::InvalidArgument("principal mapped to empty username");
  }
  local_name->assign(buf);
  return Status::OK();
}

Status GetConfiguredPrincipal(const string& in_principal, string* out_principal) {
  *out_principal = in_principal;
  static const auto& kHostToken = "_HOST";
  if (in_principal.find(kHostToken) != string::npos) {
    string hostname;
    // Try to fill in either the FQDN or hostname.
    if (!GetFQDN(&hostname).ok()) {
      RETURN_NOT_OK(GetHostname(&hostname));
    }
    // Hosts in principal names are canonicalized to lower-case.
    std::transform(hostname.begin(), hostname.end(), hostname.begin(), tolower);
    GlobalReplaceSubstring(kHostToken, hostname, out_principal);
  }
  return Status::OK();
}

optional<string> GetLoggedInPrincipalFromKeytab() {
  if (!g_kinit_ctx) {
    return nullopt;
  }
  return g_kinit_ctx->principal_str();
}

optional<string> GetLoggedInUsernameFromKeytab() {
  if (!g_kinit_ctx) {
    return nullopt;
  }
  return g_kinit_ctx->username_str();
}

Status Krb5ParseName(const string& principal, string* service_name,
                     string* hostname, string* realm) {
  krb5_principal princ;
  KRB5_RETURN_NOT_OK_PREPEND(krb5_parse_name(g_krb5_ctx, principal.c_str(), &princ),
      "could not parse principal");
  SCOPED_CLEANUP({
      krb5_free_principal(g_krb5_ctx, princ);
    });
  if (princ->length != 2) {
    return Status::InvalidArgument(Substitute("$0: principal should include "
                                              "service name, hostname and realm", principal));
  }
  realm->assign(princ->realm.data, princ->realm.length);
  service_name->assign(princ->data[0].data, princ->data[0].length);
  hostname->assign(princ->data[1].data, princ->data[1].length);
  return Status::OK();
}

Status InitKerberosForServer(const std::string& raw_principal,
                             const std::string& keytab_file,
                             const std::string& krb5ccname,
                             bool disable_krb5_replay_cache) {
  if (keytab_file.empty()) {
    return Status::OK();
  }

  PCHECK(setenv("KRB5CCNAME", krb5ccname.c_str(), 1) == 0);
  PCHECK(setenv("KRB5_KTNAME", keytab_file.c_str(), 1) == 0);

  if (disable_krb5_replay_cache) {
    // KUDU-1897: disable the Kerberos replay cache. The KRPC protocol includes a
    // per-connection server-generated nonce to protect against replay attacks
    // when authenticating via Kerberos. The replay cache has many performance and
    // implementation issues.
    PCHECK(setenv("KRB5RCACHETYPE", "none", 1) == 0);
  }

  g_kinit_ctx = new KinitContext();
  string configured_principal;
  RETURN_NOT_OK(GetConfiguredPrincipal(raw_principal, &configured_principal));
  RETURN_NOT_OK_PREPEND(g_kinit_ctx->Kinit(
      keytab_file, configured_principal), "unable to kinit");

  return Status::OK();
}

void DestroyKerberosForServer() {
  if (g_kinit_ctx == nullptr) return;

  delete g_kinit_ctx;
  g_kinit_ctx = nullptr;
}

string GetKrb5ConfigFile() {
  const char* config_file = getenv("KRB5_CONFIG");
  if (!config_file) {
    return "/etc/krb5.conf";
  }

  return string(config_file);
}

} // namespace security
} // namespace kudu

#if defined(__APPLE__)
#pragma GCC diagnostic pop
#endif // #if defined(__APPLE__)
