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

#include "brillo/cryptohome.h"

#include <openssl/sha.h>
#include <stdint.h>

#include <algorithm>
#include <cstring>
#include <limits>
#include <vector>

#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>

using base::FilePath;

namespace brillo {
namespace cryptohome {
namespace home {

const char kGuestUserName[] = "$guest";

// Path to user homes mounted with the mount_hidden option. The user home mount
// will be located at:
// kHiddenUserHomeBaseDir/<sanitized_user_name>/kHiddenUserHomeMountSubdir
const char kHiddenUserHomeBaseDir[] = "/home/.shadow";
const char kHiddenUserHomeMountSubdir[] = "mount";

// Daemon store main directory.
constexpr char kDaemonStorePath[] = "/run/daemon-store";

// Subdirectory of a user home mount where daemon-specific data is stored.
// This is used to assemble daemon data storage paths for hidden user home
// mounts.
const char kHiddenUserHomeRootSubdir[] = "root";

static char g_user_home_prefix[PATH_MAX] = "/home/user/";
static char g_root_home_prefix[PATH_MAX] = "/home/root/";
static char g_system_salt_path[PATH_MAX] = "/home/.shadow/salt";

static std::string* salt = nullptr;

bool EnsureSystemSaltIsLoaded() {
  if (salt && !salt->empty())
    return true;
  FilePath salt_path(g_system_salt_path);
  int64_t file_size;
  if (!base::GetFileSize(salt_path, &file_size)) {
    PLOG(ERROR) << "Could not get size of system salt: " << g_system_salt_path;
    return false;
  }
  if (file_size > static_cast<int64_t>(std::numeric_limits<int>::max())) {
    LOG(ERROR) << "System salt too large: " << file_size;
    return false;
  }
  std::vector<char> buf;
  buf.resize(file_size);
  unsigned int data_read = base::ReadFile(salt_path, buf.data(), file_size);
  if (data_read != file_size) {
    PLOG(ERROR) << "Could not read entire file: " << data_read
                << " != " << file_size;
    return false;
  }

  if (!salt)
    salt = new std::string();
  salt->assign(buf.data(), file_size);
  return true;
}

std::string SanitizeUserName(const std::string& username) {
  if (!EnsureSystemSaltIsLoaded())
    return std::string();

  return SanitizeUserNameWithSalt(username, SecureBlob(*salt));
}

std::string SanitizeUserNameWithSalt(const std::string& username,
                                     const SecureBlob& salt) {
  unsigned char binmd[SHA_DIGEST_LENGTH];
  std::string lowercase(username);
  std::transform(lowercase.begin(), lowercase.end(), lowercase.begin(),
                 ::tolower);
  SHA_CTX ctx;
  SHA1_Init(&ctx);
  SHA1_Update(&ctx, salt.data(), salt.size());
  SHA1_Update(&ctx, lowercase.data(), lowercase.size());
  SHA1_Final(binmd, &ctx);
  std::string final = base::HexEncode(binmd, sizeof(binmd));
  // Stay compatible with CryptoLib::HexEncodeToBuffer()
  std::transform(final.begin(), final.end(), final.begin(), ::tolower);
  return final;
}

FilePath GetUserPathPrefix() {
  return FilePath(g_user_home_prefix);
}

FilePath GetRootPathPrefix() {
  return FilePath(g_root_home_prefix);
}

FilePath GetHashedUserPath(const std::string& hashed_username) {
  return FilePath(
      base::StringPrintf("%s%s", g_user_home_prefix, hashed_username.c_str()));
}

FilePath GetUserPath(const std::string& username) {
  if (!EnsureSystemSaltIsLoaded())
    return FilePath();
  return GetHashedUserPath(SanitizeUserName(username));
}

FilePath GetRootPath(const std::string& username) {
  if (!EnsureSystemSaltIsLoaded())
    return FilePath();
  return FilePath(base::StringPrintf("%s%s", g_root_home_prefix,
                                     SanitizeUserName(username).c_str()));
}

FilePath GetDaemonStorePath(const std::string& username,
                            const std::string& daemon) {
  if (!EnsureSystemSaltIsLoaded())
    return FilePath();
  return FilePath(kDaemonStorePath)
      .Append(daemon)
      .Append(SanitizeUserName(username));
}

FilePath GetDaemonPathForHiddenUserHome(const std::string& username,
                                        const std::string& daemon) {
  if (!EnsureSystemSaltIsLoaded())
    return FilePath();

  return FilePath(kHiddenUserHomeBaseDir)
      .Append(SanitizeUserName(username))
      .Append(kHiddenUserHomeMountSubdir)
      .Append(kHiddenUserHomeRootSubdir)
      .Append(daemon);
}

bool IsSanitizedUserName(const std::string& sanitized) {
  std::vector<uint8_t> bytes;
  return (sanitized.length() == 2 * SHA_DIGEST_LENGTH) &&
         base::HexStringToBytes(sanitized, &bytes);
}

void SetUserHomePrefix(const std::string& prefix) {
  if (prefix.length() < sizeof(g_user_home_prefix)) {
    snprintf(g_user_home_prefix, sizeof(g_user_home_prefix), "%s",
             prefix.c_str());
  }
}

void SetRootHomePrefix(const std::string& prefix) {
  if (prefix.length() < sizeof(g_root_home_prefix)) {
    snprintf(g_root_home_prefix, sizeof(g_root_home_prefix), "%s",
             prefix.c_str());
  }
}

std::string* GetSystemSalt() {
  return salt;
}

void SetSystemSalt(std::string* value) {
  salt = value;
}

}  // namespace home
}  // namespace cryptohome
}  // namespace brillo
