// 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 <chromeos/secure_blob.h>

using std::string;
using base::FilePath;
using chromeos::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.const_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
