// Copyright 2017 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.

// Stub implementation of kinit. Does not talk to server, but simply returns
// fixed responses to predefined input.

#include <string>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "authpolicy/platform_helper.h"
#include "authpolicy/samba_helper.h"
#include "authpolicy/stub_common.h"

namespace authpolicy {
namespace {

// kinit error messages. stub_kinit reproduces kinit errors because authpolicy
// reads and interprets error messages from stdout/stderr.
const char kNonExistingPrincipalErrorFormat[] =
    "kinit: Client '%s' not found in Kerberos database while getting initial "
    "credentials";
const char kWrongPasswordError[] =
    "kinit: Preauthentication failed while getting initial credentials";
const char kPasswordExpiredStdout[] =
    "Password expired.  You must change it now.";
const char kPasswordRejectedStdout[] =
    "Password for user@realm:"
    "Password expired.  You must change it now.\n"
    "Enter new password:\n"
    "Enter it again:\n"
    "Password change rejected: The password must include numbers or symbols.  "
    "Don't include any part of your name in the password.  The password must "
    "contain at least 7 characters.  The password must be different from the "
    "previous 24 passwords.  The password can only be changed once a day..  "
    "Please try again.";
const char kCannotReadPasswordStderr[] =
    "Cannot read password while getting initial credentials";
const char kNetworkError[] = "Cannot resolve network address for KDC in realm";
const char kCannotContactKdc[] = "Cannot contact any KDC";
const char kKdcIpKey[] = "kdc = [";
const char kPasswordWillExpireWarning[] =
    "Warning: Your password will expire in 7 days on Fri May 19 14:28:41 2017";
const char kRefresh[] = "-R";
const char kTicketExpired[] =
    "kinit: Ticket expired while renewing credentials";
const char kEncTypeNotSupported[] =
    "KDC has no support for encryption type while getting initial credentials";

// Returns upper-cased |machine_name|$@|kUserRealm|.
std::string MakeMachinePrincipal(const std::string& machine_name) {
  return base::ToUpperASCII(machine_name) + "$@" + kUserRealm;
}

// For a given |machine_name|, tests if the |command_line| starts with
// corresponding machine principal part (upper-cased |machine_name| + "$@").
bool TestMachinePrincipal(const std::string& command_line,
                          const std::string& machine_name) {
  std::string machine_principal_part = base::ToUpperASCII(machine_name) + "$@";
  return StartsWithCaseSensitive(command_line, machine_principal_part.c_str());
}

// Returns true if |command_line| contains a machine principal and not a user
// principal.
bool HasMachinePrincipal(const std::string& command_line) {
  return Contains(command_line, "$@");
}

// Returns false for the first |kNumPropagationRetries| times the method is
// called and true afterwards. Used to simulate account propagation errors. Only
// works once per test. Uses a test file internally, where each time a byte is
// appended to count retries. Note that each invokation usually happens in a
// separate process, so a static memory location can't be used for counting.
bool HasStubAccountPropagated() {
  const auto test_dir = base::FilePath(GetKrb5ConfFilePath()).DirName();
  return PostIncTestCounter(test_dir) == kNumPropagationRetries;
}

// Reads the contents of the file at |kExpectedMachinePassFilename| and returns
// it in |expected_machine_pass|. Returns false if it doesn't exist.
bool GetExpectedMachinePassword(std::string* expected_machine_pass) {
  const base::FilePath krb5_conf_path(GetKrb5ConfFilePath());
  const base::FilePath expected_password_path =
      krb5_conf_path.DirName().Append(kExpectedMachinePassFilename);
  if (!base::PathExists(expected_password_path))
    return false;

  CHECK(base::ReadFileToString(base::FilePath(expected_password_path),
                               expected_machine_pass));
  return true;
}

// Writes a stub Kerberos credentials cache to the file path given by the
// kKrb5CCEnvKey environment variable.
void WriteKrb5CC(const std::string& data) {
  const std::string krb5cc_path = GetKrb5CCFilePath();
  // Note: base::WriteFile triggers a seccomp failure, so do it old-school.
  base::ScopedFILE krb5cc_file(fopen(krb5cc_path.c_str(), "w"));
  CHECK(krb5cc_file);
  CHECK_EQ(1U, fwrite(data.c_str(), data.size(), 1, krb5cc_file.get()));
}

// Checks whether the Kerberos configuration file contains the KDC IP.
bool Krb5ConfContainsKdcIp() {
  const base::FilePath krb5_conf_path(GetKrb5ConfFilePath());
  std::string krb5_conf;
  CHECK(base::ReadFileToString(krb5_conf_path, &krb5_conf));
  return Contains(krb5_conf, kKdcIpKey);
}

// Handles ticket refresh with kinit -R. Switches behavior based on the contents
// of the Kerberos ticket.
int HandleRefresh() {
  const std::string krb5cc_path = GetKrb5CCFilePath();
  std::string krb5cc_data;
  CHECK(base::ReadFileToString(base::FilePath(krb5cc_path), &krb5cc_data));
  if (krb5cc_data == kExpiredKrb5CCData) {
    WriteOutput("", kTicketExpired);
    return kExitCodeError;
  }
  WriteKrb5CC(kValidKrb5CCData);
  return kExitCodeOk;
}

int HandleCommandLine(const std::string& command_line) {
  // Read the password from stdin.
  std::string password;
  if (!ReadPipeToString(STDIN_FILENO, &password)) {
    LOG(ERROR) << "Failed to read password";
    return kExitCodeError;
  }

  // Request for TGT refresh. The only test that uses it expects a failure.
  if (StartsWithCaseSensitive(command_line, kRefresh))
    return HandleRefresh();

  // Stub non-existing account error.
  if (StartsWithCaseSensitive(command_line, kNonExistingUserPrincipal)) {
    WriteOutput("", base::StringPrintf(kNonExistingPrincipalErrorFormat,
                                       kNonExistingUserPrincipal));
    return kExitCodeError;
  }

  // Stub network error.
  if (StartsWithCaseSensitive(command_line, kNetworkErrorUserPrincipal)) {
    WriteOutput("", kNetworkError);
    return kExitCodeError;
  }

  // Stub kinit retry if the krb5.conf contains the KDC IP.
  if (StartsWithCaseSensitive(command_line, kKdcRetryUserPrincipal)) {
    if (Krb5ConfContainsKdcIp()) {
      WriteOutput("", kCannotContactKdc);
      return kExitCodeError;
    }
    WriteKrb5CC(kValidKrb5CCData);
    return kExitCodeOk;
  }

  // Stub kinit retry, but fail the second time as well.
  if (StartsWithCaseSensitive(command_line, kKdcRetryFailsUserPrincipal)) {
    WriteOutput("", kCannotContactKdc);
    return kExitCodeError;
  }

  // Stub encryption type not supported error.
  if (StartsWithCaseSensitive(command_line,
                              kEncTypeNotSupportedUserPrincipal)) {
    WriteOutput("", kEncTypeNotSupported);
    return kExitCodeError;
  }

  // Stub expired credential cache.
  if (StartsWithCaseSensitive(command_line, kExpiredTgtUserPrincipal)) {
    WriteKrb5CC(kExpiredKrb5CCData);
    return kExitCodeOk;
  }

  // Stub seccomp failure.
  if (StartsWithCaseSensitive(command_line, kSeccompUserPrincipal)) {
    TriggerSeccompFailure();
    WriteKrb5CC(kValidKrb5CCData);
    return kExitCodeOk;
  }

  // Stub valid user principal. Switch behavior based on password.
  if (StartsWithCaseSensitive(command_line, kUserPrincipal) ||
      StartsWithCaseSensitive(command_line, kPasswordChangedUserPrincipal) ||
      StartsWithCaseSensitive(command_line, kNoPwdFieldsUserPrincipal)) {
    // Stub wrong password error.
    if (password == kWrongPassword) {
      WriteOutput("", kWrongPasswordError);
      return kExitCodeError;
    }

    // Stub expired password error.
    if (password == kExpiredPassword) {
      WriteOutput(kPasswordExpiredStdout, kCannotReadPasswordStderr);
      return kExitCodeError;
    }

    // Stub rejected password error.
    if (password == kRejectedPassword) {
      WriteOutput(kPasswordRejectedStdout, kCannotReadPasswordStderr);
      return kExitCodeError;
    }

    // Stub warning that the password will expire soon.
    if (password == kWillExpirePassword) {
      WriteKrb5CC(kValidKrb5CCData);
      WriteOutput(kPasswordWillExpireWarning, "");
      return kExitCodeOk;
    }

    // Stub valid password.
    if (password == kPassword) {
      WriteKrb5CC(kValidKrb5CCData);
      return kExitCodeOk;
    }

    NOTREACHED() << "UNHANDLED PASSWORD " << password;
    return kExitCodeError;
  }

  // Handle machine principals.
  if (HasMachinePrincipal(command_line)) {
    // Stub account propagation error.
    if (TestMachinePrincipal(command_line, kExpectKeytabMachineName)) {
      // Make sure the caller adds the debug level.
      CHECK(Contains(command_line, kUseKeytabParam));
      CHECK(password.empty());
      std::string keytab_path = GetKeytabFilePath();
      CHECK(!keytab_path.empty());
      WriteKrb5CC(kValidKrb5CCData);
      return kExitCodeOk;
    }

    // The ones below should be using a password.
    CheckMachinePassword(password);

    // Compare to the expected password, if it exists.
    std::string expected_password;
    if (GetExpectedMachinePassword(&expected_password) &&
        password != expected_password) {
      WriteOutput("", kWrongPasswordError);
      return kExitCodeError;
    }

    // Stub account propagation error.
    if (TestMachinePrincipal(command_line, kPropagationRetryMachineName) &&
        !HasStubAccountPropagated()) {
      WriteOutput(
          "", base::StringPrintf(
                  kNonExistingPrincipalErrorFormat,
                  MakeMachinePrincipal(kPropagationRetryMachineName).c_str()));
      return kExitCodeError;
    }

    // Stub non-existent machine error (e.g. machine got deleted from ACtive
    // Directory).
    if (TestMachinePrincipal(command_line, kNonExistingMachineName)) {
      // Note: Same error as if the account hasn't propagated yet.
      WriteOutput("",
                  base::StringPrintf(
                      kNonExistingPrincipalErrorFormat,
                      MakeMachinePrincipal(kNonExistingMachineName).c_str()));
      return kExitCodeError;
    }

    // All other machine principals just pass.
    WriteKrb5CC(kValidKrb5CCData);
    return kExitCodeOk;
  }

  NOTREACHED() << "UNHANDLED COMMAND LINE " << command_line;
  return kExitCodeError;
}

}  // namespace
}  // namespace authpolicy

int main(int argc, char* argv[]) {
  std::string command_line = authpolicy::GetCommandLine(argc, argv);
  return authpolicy::HandleCommandLine(command_line);
}
