#include "env-inl.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 <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::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
using v8::String;
using v8::TryCatch;
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.
bool HasOnly(int capability) {
  DCHECK(cap_valid(capability));

  struct __user_cap_data_struct cap_data[2];
  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;
  }
  if (capability < 32) {
    return cap_data[0].permitted ==
        static_cast<unsigned int>(CAP_TO_MASK(capability));
  }
  return cap_data[1].permitted ==
      static_cast<unsigned int>(CAP_TO_MASK(capability));
}
#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,
                v8::Isolate* isolate) {
#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
    goto fail;
#endif

  if (env_vars != nullptr) {
    DCHECK_NOT_NULL(isolate);
    HandleScope handle_scope(isolate);
    TryCatch ignore_errors(isolate);
    MaybeLocal<String> maybe_value = env_vars->Get(
        isolate, String::NewFromUtf8(isolate, key).ToLocalChecked());
    Local<String> value;
    if (!maybe_value.ToLocal(&value)) goto fail;
    String::Utf8Value utf8_value(isolate, value);
    if (*utf8_value == nullptr) goto fail;
    *text = std::string(*utf8_value, utf8_value.length());
    return true;
  }

  {
    Mutex::ScopedLock lock(per_process::env_var_mutex);

    size_t init_sz = 256;
    MaybeStackBuffer<char, 256> val;
    int ret = uv_os_getenv(key, *val, &init_sz);

    if (ret == UV_ENOBUFS) {
      // Buffer is not large enough, reallocate to the updated init_sz
      // and fetch env value again.
      val.AllocateSufficientStorage(init_sz);
      ret = uv_os_getenv(key, *val, &init_sz);
    }

    if (ret >= 0) {  // Env key value fetch success.
      *text = *val;
      return true;
    }
  }

fail:
  text->clear();
  return false;
}

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(), isolate)) 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()) {
    return static_cast<uid_t>(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()) {
    return static_cast<gid_t>(value.As<Uint32>()->Value());
  } else {
    Utf8Value name(isolate, value);
    return gid_by_name(*name);
  }
}

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());

  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());

  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());

  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());

  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());

  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());

  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) {
  Environment* env = Environment::GetCurrent(context);
  Isolate* isolate = env->isolate();

  SetMethod(context, target, "safeGetenv", SafeGetenv);

#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
  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_MODULE_CONTEXT_AWARE_INTERNAL(credentials, node::credentials::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(credentials,
                               node::credentials::RegisterExternalReferences)
