#include "env-inl.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_internals.h"
#include "util-inl.h"

#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
#include <grp.h>  // getgrnam()
#include <pwd.h>  // getpwnam()
#endif            // NODE_IMPLEMENTS_POSIX_CREDENTIALS

#if !defined(_MSC_VER)
#include <unistd.h>  // setuid, getuid
#endif
#ifdef __linux__
#include <dlfcn.h>  // dlsym()
#include <linux/capability.h>
#include <sys/auxv.h>
#include <sys/syscall.h>
#endif  // __linux__

namespace node {

using v8::Array;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
using v8::Uint32;
using v8::Value;

bool linux_at_secure() {
  // This could reasonably be a static variable, but this way
  // we can guarantee that this function is always usable
  // and returns the correct value,  e.g. even in static
  // initialization code in other files.
#ifdef __linux__
  static const bool value = getauxval(AT_SECURE);
  return value;
#else
  return false;
#endif
}

namespace credentials {

#if defined(__linux__)
// Returns true if the current process only has the passed-in capability.
static bool HasOnly(int capability) {
  DCHECK(cap_valid(capability));

  struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3];
  struct __user_cap_header_struct cap_header_data = {
    _LINUX_CAPABILITY_VERSION_3,
    getpid()};


  if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) {
    return false;
  }

  static_assert(arraysize(cap_data) == 2);
  return cap_data[CAP_TO_INDEX(capability)].permitted ==
             static_cast<unsigned int>(CAP_TO_MASK(capability)) &&
         cap_data[1 - CAP_TO_INDEX(capability)].permitted == 0;
}
#endif

// Look up the environment variable and allow the lookup if the current
// process only has the capability CAP_NET_BIND_SERVICE set. If the current
// process does not have any capabilities set and the process is running as
// setuid root then lookup will not be allowed.
bool SafeGetenv(const char* key,
                std::string* text,
                std::shared_ptr<KVStore> env_vars) {
#if !defined(__CloudABI__) && !defined(_WIN32)
#if defined(__linux__)
  if ((!HasOnly(CAP_NET_BIND_SERVICE) && linux_at_secure()) ||
      getuid() != geteuid() || getgid() != getegid())
#else
  if (linux_at_secure() || getuid() != geteuid() || getgid() != getegid())
#endif
    return false;
#endif

  // Fallback to system environment which reads the real environment variable
  // through uv_os_getenv.
  if (env_vars == nullptr) {
    env_vars = per_process::system_environment;
  }

  return env_vars->Get(key).To(text);
}

static void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
  CHECK(args[0]->IsString());
  Environment* env = Environment::GetCurrent(args);
  Isolate* isolate = env->isolate();
  Utf8Value strenvtag(isolate, args[0]);
  std::string text;
  if (!SafeGetenv(*strenvtag, &text, env->env_vars())) return;
  Local<Value> result =
      ToV8Value(isolate->GetCurrentContext(), text).ToLocalChecked();
  args.GetReturnValue().Set(result);
}

#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS

static const uid_t uid_not_found = static_cast<uid_t>(-1);
static const gid_t gid_not_found = static_cast<gid_t>(-1);

static uid_t uid_by_name(const char* name) {
  struct passwd pwd;
  struct passwd* pp;
  char buf[8192];

  errno = 0;
  pp = nullptr;

  if (getpwnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
    return pp->pw_uid;

  return uid_not_found;
}

static char* name_by_uid(uid_t uid) {
  struct passwd pwd;
  struct passwd* pp;
  char buf[8192];
  int rc;

  errno = 0;
  pp = nullptr;

  if ((rc = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
      pp != nullptr) {
    return strdup(pp->pw_name);
  }

  if (rc == 0) errno = ENOENT;

  return nullptr;
}

static gid_t gid_by_name(const char* name) {
  struct group pwd;
  struct group* pp;
  char buf[8192];

  errno = 0;
  pp = nullptr;

  if (getgrnam_r(name, &pwd, buf, sizeof(buf), &pp) == 0 && pp != nullptr)
    return pp->gr_gid;

  return gid_not_found;
}

#if 0  // For future use.
static const char* name_by_gid(gid_t gid) {
  struct group pwd;
  struct group* pp;
  char buf[8192];
  int rc;

  errno = 0;
  pp = nullptr;

  if ((rc = getgrgid_r(gid, &pwd, buf, sizeof(buf), &pp)) == 0 &&
      pp != nullptr) {
    return strdup(pp->gr_name);
  }

  if (rc == 0)
    errno = ENOENT;

  return nullptr;
}
#endif

static uid_t uid_by_name(Isolate* isolate, Local<Value> value) {
  if (value->IsUint32()) {
    static_assert(std::is_same<uid_t, uint32_t>::value);
    return value.As<Uint32>()->Value();
  } else {
    Utf8Value name(isolate, value);
    return uid_by_name(*name);
  }
}

static gid_t gid_by_name(Isolate* isolate, Local<Value> value) {
  if (value->IsUint32()) {
    static_assert(std::is_same<gid_t, uint32_t>::value);
    return value.As<Uint32>()->Value();
  } else {
    Utf8Value name(isolate, value);
    return gid_by_name(*name);
  }
}

#ifdef __linux__
extern "C" {
int uv__node_patch_is_using_io_uring(void);

int uv__node_patch_is_using_io_uring(void) __attribute__((weak));

typedef int (*is_using_io_uring_fn)(void);
}
#endif  // __linux__

static bool UvMightBeUsingIoUring() {
#ifdef __linux__
  // Support for io_uring is only included in libuv 1.45.0 and later, and only
  // on Linux (and Android, but there it is always disabled). The patch that we
  // apply to libuv to work around the io_uring security issue adds a function
  // that tells us whether io_uring is being used. If that function is not
  // present, we assume that we are dynamically linking against an unpatched
  // version.
  static std::atomic<is_using_io_uring_fn> check =
      uv__node_patch_is_using_io_uring;
  if (check == nullptr) {
    check = reinterpret_cast<is_using_io_uring_fn>(
        dlsym(RTLD_DEFAULT, "uv__node_patch_is_using_io_uring"));
  }
  return uv_version() >= 0x012d00u && (check == nullptr || (*check)());
#else
  return false;
#endif
}

static bool ThrowIfUvMightBeUsingIoUring(Environment* env, const char* fn) {
  if (UvMightBeUsingIoUring()) {
    node::THROW_ERR_INVALID_STATE(
        env, "%s() disabled: io_uring may be enabled. See CVE-2024-22017.", fn);
    return true;
  }
  return false;
}

static void GetUid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->has_run_bootstrapping_code());
  // uid_t is an uint32_t on all supported platforms.
  args.GetReturnValue().Set(static_cast<uint32_t>(getuid()));
}

static void GetGid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->has_run_bootstrapping_code());
  // gid_t is an uint32_t on all supported platforms.
  args.GetReturnValue().Set(static_cast<uint32_t>(getgid()));
}

static void GetEUid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->has_run_bootstrapping_code());
  // uid_t is an uint32_t on all supported platforms.
  args.GetReturnValue().Set(static_cast<uint32_t>(geteuid()));
}

static void GetEGid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->has_run_bootstrapping_code());
  // gid_t is an uint32_t on all supported platforms.
  args.GetReturnValue().Set(static_cast<uint32_t>(getegid()));
}

static void SetGid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->owns_process_state());

  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsUint32() || args[0]->IsString());

  if (ThrowIfUvMightBeUsingIoUring(env, "setgid")) return;

  gid_t gid = gid_by_name(env->isolate(), args[0]);

  if (gid == gid_not_found) {
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    args.GetReturnValue().Set(1);
  } else if (setgid(gid)) {
    env->ThrowErrnoException(errno, "setgid");
  } else {
    args.GetReturnValue().Set(0);
  }
}

static void SetEGid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->owns_process_state());

  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsUint32() || args[0]->IsString());

  if (ThrowIfUvMightBeUsingIoUring(env, "setegid")) return;

  gid_t gid = gid_by_name(env->isolate(), args[0]);

  if (gid == gid_not_found) {
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    args.GetReturnValue().Set(1);
  } else if (setegid(gid)) {
    env->ThrowErrnoException(errno, "setegid");
  } else {
    args.GetReturnValue().Set(0);
  }
}

static void SetUid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->owns_process_state());

  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsUint32() || args[0]->IsString());

  if (ThrowIfUvMightBeUsingIoUring(env, "setuid")) return;

  uid_t uid = uid_by_name(env->isolate(), args[0]);

  if (uid == uid_not_found) {
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    args.GetReturnValue().Set(1);
  } else if (setuid(uid)) {
    env->ThrowErrnoException(errno, "setuid");
  } else {
    args.GetReturnValue().Set(0);
  }
}

static void SetEUid(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->owns_process_state());

  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsUint32() || args[0]->IsString());

  if (ThrowIfUvMightBeUsingIoUring(env, "seteuid")) return;

  uid_t uid = uid_by_name(env->isolate(), args[0]);

  if (uid == uid_not_found) {
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    args.GetReturnValue().Set(1);
  } else if (seteuid(uid)) {
    env->ThrowErrnoException(errno, "seteuid");
  } else {
    args.GetReturnValue().Set(0);
  }
}

static void GetGroups(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  CHECK(env->has_run_bootstrapping_code());

  int ngroups = getgroups(0, nullptr);
  if (ngroups == -1) return env->ThrowErrnoException(errno, "getgroups");

  std::vector<gid_t> groups(ngroups);

  ngroups = getgroups(ngroups, groups.data());
  if (ngroups == -1)
    return env->ThrowErrnoException(errno, "getgroups");

  groups.resize(ngroups);
  gid_t egid = getegid();
  if (std::find(groups.begin(), groups.end(), egid) == groups.end())
    groups.push_back(egid);
  MaybeLocal<Value> array = ToV8Value(env->context(), groups);
  if (!array.IsEmpty())
    args.GetReturnValue().Set(array.ToLocalChecked());
}

static void SetGroups(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);

  CHECK_EQ(args.Length(), 1);
  CHECK(args[0]->IsArray());

  if (ThrowIfUvMightBeUsingIoUring(env, "setgroups")) return;

  Local<Array> groups_list = args[0].As<Array>();
  size_t size = groups_list->Length();
  MaybeStackBuffer<gid_t, 64> groups(size);

  for (size_t i = 0; i < size; i++) {
    gid_t gid = gid_by_name(
        env->isolate(), groups_list->Get(env->context(), i).ToLocalChecked());

    if (gid == gid_not_found) {
      // Tells JS to throw ERR_INVALID_CREDENTIAL
      args.GetReturnValue().Set(static_cast<uint32_t>(i + 1));
      return;
    }

    groups[i] = gid;
  }

  int rc = setgroups(size, *groups);

  if (rc == -1) return env->ThrowErrnoException(errno, "setgroups");

  args.GetReturnValue().Set(0);
}

static void InitGroups(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);

  CHECK_EQ(args.Length(), 2);
  CHECK(args[0]->IsUint32() || args[0]->IsString());
  CHECK(args[1]->IsUint32() || args[1]->IsString());

  if (ThrowIfUvMightBeUsingIoUring(env, "initgroups")) return;

  Utf8Value arg0(env->isolate(), args[0]);
  gid_t extra_group;
  bool must_free;
  char* user;

  if (args[0]->IsUint32()) {
    user = name_by_uid(args[0].As<Uint32>()->Value());
    must_free = true;
  } else {
    user = *arg0;
    must_free = false;
  }

  if (user == nullptr) {
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    return args.GetReturnValue().Set(1);
  }

  extra_group = gid_by_name(env->isolate(), args[1]);

  if (extra_group == gid_not_found) {
    if (must_free) free(user);
    // Tells JS to throw ERR_INVALID_CREDENTIAL
    return args.GetReturnValue().Set(2);
  }

  int rc = initgroups(user, extra_group);

  if (must_free) free(user);

  if (rc) return env->ThrowErrnoException(errno, "initgroups");

  args.GetReturnValue().Set(0);
}

#endif  // NODE_IMPLEMENTS_POSIX_CREDENTIALS

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
  registry->Register(SafeGetenv);

#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
  registry->Register(GetUid);
  registry->Register(GetEUid);
  registry->Register(GetGid);
  registry->Register(GetEGid);
  registry->Register(GetGroups);

  registry->Register(InitGroups);
  registry->Register(SetEGid);
  registry->Register(SetEUid);
  registry->Register(SetGid);
  registry->Register(SetUid);
  registry->Register(SetGroups);
#endif  // NODE_IMPLEMENTS_POSIX_CREDENTIALS
}

static void Initialize(Local<Object> target,
                       Local<Value> unused,
                       Local<Context> context,
                       void* priv) {
  SetMethod(context, target, "safeGetenv", SafeGetenv);

#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
  Environment* env = Environment::GetCurrent(context);
  Isolate* isolate = env->isolate();

  READONLY_TRUE_PROPERTY(target, "implementsPosixCredentials");
  SetMethodNoSideEffect(context, target, "getuid", GetUid);
  SetMethodNoSideEffect(context, target, "geteuid", GetEUid);
  SetMethodNoSideEffect(context, target, "getgid", GetGid);
  SetMethodNoSideEffect(context, target, "getegid", GetEGid);
  SetMethodNoSideEffect(context, target, "getgroups", GetGroups);

  if (env->owns_process_state()) {
    SetMethod(context, target, "initgroups", InitGroups);
    SetMethod(context, target, "setegid", SetEGid);
    SetMethod(context, target, "seteuid", SetEUid);
    SetMethod(context, target, "setgid", SetGid);
    SetMethod(context, target, "setuid", SetUid);
    SetMethod(context, target, "setgroups", SetGroups);
  }
#endif  // NODE_IMPLEMENTS_POSIX_CREDENTIALS
}

}  // namespace credentials
}  // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(credentials, node::credentials::Initialize)
NODE_BINDING_EXTERNAL_REFERENCE(credentials,
                                node::credentials::RegisterExternalReferences)
