// Copyright (c) 2013 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.

// This provides some utility functions to do with chaps isolate support.

#include "chaps/isolate.h"

#include <grp.h>
#include <pwd.h>

#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <brillo/secure_blob.h>

using std::string;
using base::FilePath;
using brillo::SecureBlob;

namespace chaps {

namespace {

const FilePath::CharType kIsolateFilePath[] =
    FILE_PATH_LITERAL("/var/lib/chaps/isolates/");

}  // namespace

IsolateCredentialManager::IsolateCredentialManager() { }

IsolateCredentialManager::~IsolateCredentialManager() { }

bool IsolateCredentialManager::GetCurrentUserIsolateCredential(
    SecureBlob* isolate_credential) {
  CHECK(isolate_credential);

  const uid_t uid = getuid();
  long buf_len = sysconf(_SC_GETPW_R_SIZE_MAX);  // NOLINT(runtime/int)
  if (buf_len < 0)
    buf_len = 4096;
  passwd pwd_buf;
  passwd* pwd = nullptr;
  std::vector<char> buf(buf_len);
  if (getpwuid_r(uid, &pwd_buf, buf.data(), buf_len, &pwd) || !pwd) {
    PLOG(ERROR) << "Failed to get user information for current user.";
    return false;
  }

  return GetUserIsolateCredential(pwd->pw_name, isolate_credential);
}

bool IsolateCredentialManager::GetUserIsolateCredential(
    const string& user,
    SecureBlob* isolate_credential) {
  CHECK(isolate_credential);

  string credential_string;
  const FilePath credential_file = FilePath(kIsolateFilePath).Append(user);
  if (!base::PathExists(credential_file) ||
      !base::ReadFileToString(credential_file, &credential_string)) {
    LOG(INFO) << "Failed to find or read isolate credential for user "
              << user;
    return false;
  }
  const SecureBlob new_isolate_credential(credential_string);
  if (new_isolate_credential.size() != kIsolateCredentialBytes) {
    LOG(ERROR) << "Isolate credential invalid for user " << user;
    return false;
  }

  *isolate_credential = new_isolate_credential;
  return true;
}

bool IsolateCredentialManager::SaveIsolateCredential(
    const string& user,
    const SecureBlob& isolate_credential) {
  CHECK_EQ(kIsolateCredentialBytes, isolate_credential.size());

  // Look up user information.
  long buf_len = sysconf(_SC_GETPW_R_SIZE_MAX);  // NOLINT(runtime/int)
  if (buf_len < 0)
    buf_len = 4096;
  passwd pwd_buf;
  passwd* pwd = nullptr;
  std::vector<char> buf(buf_len);
  if (getpwnam_r(user.c_str(), &pwd_buf, buf.data(), buf_len, &pwd) || !pwd) {
    LOG(ERROR) << "Failed to get user information.";
    return false;
  }

  // Write the isolate credential file.
  const FilePath isolate_cred_file = FilePath(kIsolateFilePath).Append(user);
  int bytes_written = base::WriteFile(
      isolate_cred_file,
      reinterpret_cast<const char *>(isolate_credential.data()),
      kIsolateCredentialBytes);
  if (bytes_written != static_cast<int>(kIsolateCredentialBytes)) {
    LOG(ERROR) << "Failed to create isolate file for user " << user;
    return false;
  }

  // Change permissions to be readable by (and only by) the user.
  if (chmod(isolate_cred_file.value().c_str(), S_IRUSR)) {
    LOG(ERROR) << "Failed to change permissions of isolate file.";
    return false;
  }
  if (chown(isolate_cred_file.value().c_str(), pwd->pw_uid, pwd->pw_gid)) {
    LOG(ERROR) << "Failed to change ownership of isolate file.";
    return false;
  }

  return true;
}

}  // namespace chaps
