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

#include <openssl/sha.h>

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

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

using base::FilePath;

namespace chromeos {
namespace cryptohome {
namespace home {

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 = NULL;

static bool EnsureSystemSaltIsLoaded() {
  if (salt && !salt->empty())
    return true;
  FilePath salt_path(g_system_salt_path);
  int64 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>(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.front(), 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.front(), file_size);
  return true;
}

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

  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::AsciiEncodeToBuffer()
  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 GetDaemonPath(const std::string& username, const std::string& daemon) {
  if (!EnsureSystemSaltIsLoaded())
    return FilePath("");
  return GetRootPath(username).Append(daemon);
}

bool IsSanitizedUserName(const std::string& sanitized) {
  std::vector<uint8> 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))
    strcpy(g_user_home_prefix, prefix.c_str());
}

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

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

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

} // namespace home
} // namespace cryptohome
} // namespace chromeos
