// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/run_level.h"

#ifdef OS_WIN
#include <windows.h>
#include <aclapi.h>
#endif  // OS_WIN

#ifdef OS_MACOSX
#include <unistd.h>
#endif  // OS_MACOSX

#ifdef OS_LINUX
#include <unistd.h>
#include <sys/types.h>
#endif  // OS_LINUX

#include "base/const.h"
#include "base/logging.h"
#include "base/scoped_handle.h"
#include "base/system_util.h"
#include "base/util.h"
#include "base/win_sandbox.h"
#include "base/win_util.h"

namespace mozc {
namespace {

#ifdef OS_WIN
const wchar_t kElevatedProcessDisabledName[]
= L"elevated_process_disabled";

// Returns true if both array have the same content.
template <typename T, size_t ArraySize>
bool AreEqualArray(const T (&lhs)[ArraySize], const T (&rhs)[ArraySize]) {
  for (size_t i = 0; i < ArraySize; ++i) {
    if (lhs[i] != rhs[i]) {
      return false;
    }
  }
  return true;
}

// returns true if the token was created by Secondary Logon
// (typically via RunAs command) or UAC (w/ alternative credential provided)
//  or if failed to determine.
bool IsDifferentUser(const HANDLE hToken) {
  TOKEN_SOURCE src;
  DWORD        dwReturnedBc;

  // Get TOKEN_SOURCE
  if (!::GetTokenInformation(hToken, TokenSource,
                             &src, sizeof(src), &dwReturnedBc)) {
    // Most likely there was an error.
    return true;
  }

  // SourceName is not always null-terminated.
  //  We're looking for the cases marked '->'.
  //  Vista SP1 (Normal)                     "User32 \0"
  //  ->  Vista SP1 (RunAs):                 "seclogo\0"
  //  ->  Vista SP1 (Over-the-shoulder UAC): "CredPro\0"

  // Sacrifice the last character. That is practically ok for our purpose.
  src.SourceName[TOKEN_SOURCE_LENGTH - 1] = '\0';

  const char kSeclogo[] = "seclogo";
  const char kCredPro[] = "CredPro";

  return (AreEqualArray(kSeclogo, src.SourceName) ||
          AreEqualArray(kCredPro, src.SourceName));
}

// Returns true if UAC gave the high integrity level to the token
// or if failed to determine.
// This code is written by thatanaka
bool IsElevatedByUAC(const HANDLE hToken) {
  // Get TokenElevationType.
  DWORD dwSize;
  TOKEN_ELEVATION_TYPE ElevationType;
  if (!::GetTokenInformation(hToken, TokenElevationType, &ElevationType,
                             sizeof(ElevationType), &dwSize )) {
    return true;
  }

  // Only TokenElevationTypeFull means the process token was elevated by UAC.
  if (TokenElevationTypeFull != ElevationType) {
    return false;
  }

  // Although rare, it is still possible for an elevated token to have a lower
  // integrity level.
  // Checking to see if it is actually higher than medium.

  // Get TokenIntegrityLevel.
  BYTE buffer[sizeof(TOKEN_MANDATORY_LABEL) + SECURITY_MAX_SID_SIZE];
  if (!::GetTokenInformation(hToken, TokenIntegrityLevel, buffer,
                             sizeof(buffer), &dwSize )) {
    return true;
  }

  PTOKEN_MANDATORY_LABEL pMandatoryLabel =
      reinterpret_cast<PTOKEN_MANDATORY_LABEL>(buffer);

  // Since the SID was acquired from token, it should be always valid.
  DCHECK(::IsValidSid(pMandatoryLabel->Label.Sid));

  // Find the integrity level RID.
  PDWORD pdwIntegrityLevelRID;
  pdwIntegrityLevelRID = ::GetSidSubAuthority(pMandatoryLabel->Label.Sid,
                                              0 /* index 0 always exists */);
  if (!pdwIntegrityLevelRID) {
    return true;
  }

  return (SECURITY_MANDATORY_MEDIUM_RID < *pdwIntegrityLevelRID);
}
#endif   // OS_WIN
}  // namespace

RunLevel::RunLevelType RunLevel::GetRunLevel(RunLevel::RequestType type) {
#ifdef OS_WIN
  bool is_service_process = false;
  if (!WinUtil::IsServiceProcess(&is_service_process)) {
    // Returns DENY conservatively.
    return RunLevel::DENY;
  }
  if (is_service_process) {
    return RunLevel::DENY;
  }

  // Get process token
  HANDLE hProcessToken = NULL;
  if (!::OpenProcessToken(::GetCurrentProcess(),
                          TOKEN_QUERY | TOKEN_QUERY_SOURCE,
                          &hProcessToken)) {
    return RunLevel::DENY;
  }

  ScopedHandle process_token(hProcessToken);

  // Opt out of elevated process.
  if (CLIENT == type &&
      GetElevatedProcessDisabled() &&
      mozc::IsElevatedByUAC(process_token.get())) {
    return RunLevel::DENY;
  }

  // Get thread token (if any)
  HANDLE hThreadToken = NULL;
  if (!::OpenThreadToken(::GetCurrentThread(),
                         TOKEN_QUERY, TRUE, &hThreadToken) &&
      ERROR_NO_TOKEN != ::GetLastError()) {
    return RunLevel::DENY;
  }

  ScopedHandle thread_token(hThreadToken);

  // Thread token (if any) must not a service account.
  if (NULL != thread_token.get()) {
    bool is_service_thread = false;
    if (!WinUtil::IsServiceUser(thread_token.get(), &is_service_thread)) {
      // Returns DENY conservatively.
      return RunLevel::DENY;
    }
    if (is_service_thread) {
      return RunLevel::DENY;
    }
  }

  // Check whether the server/renderer is running inside sandbox.
  if (type == SERVER || type == RENDERER) {
    // Restricted token must be created by sandbox.
    // Server is launched with NON_ADMIN so that it can use SSL access.
    // This is why it doesn't have restricted token. b/5502343
    if (type != SERVER && !::IsTokenRestricted(process_token.get())) {
      return RunLevel::DENY;
    }

    // Thread token must be created by sandbox.
    if (NULL == thread_token.get()){
      return RunLevel::DENY;
    }

    // Get the server path before the process is sandboxed.
    // SHGetFolderPath may fail in a sandboxed process.
    // See http://b/2301066 for details.
    const volatile string sys_dir = SystemUtil::GetServerDirectory();

    // Get the user profile path here because of the same reason.
    // See http://b/2301066 for details.
    const string user_dir = SystemUtil::GetUserProfileDirectory();

    wstring dir;
    Util::UTF8ToWide(user_dir.c_str(), &dir);
    ScopedHandle dir_handle(::CreateFile(dir.c_str(),
                                         READ_CONTROL | WRITE_DAC,
                                         0,
                                         NULL,
                                         OPEN_EXISTING,
                                         FILE_FLAG_BACKUP_SEMANTICS,
                                         0));
    if (NULL != dir_handle.get()) {
      BYTE buffer[sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE];
      DWORD size = 0;
      if (::GetTokenInformation(thread_token.get(), TokenUser,
                                buffer, sizeof(buffer), &size)) {
        PTOKEN_USER ptoken_user = reinterpret_cast<PTOKEN_USER>(buffer);
        // Looks like in some environment, the profile foler's permission
        // includes Administrators but does not include the user himself.
        // In such a case, Mozc wouldn't work because Administrators identity
        // is removed by sandboxing so we should recover the permission here.
        // See http://b/2317718 for details.
        WinSandbox::AddKnownSidToKernelObject(
            dir_handle.get(), static_cast<SID *>(ptoken_user->User.Sid),
            SUB_CONTAINERS_AND_OBJECTS_INHERIT, GENERIC_ALL);
      }
    }

    // Revert from the impersonation token supplied by sandbox.
    // Note: This succeeds even when the thread is not impersonating.
    if (!::RevertToSelf()) {
      return RunLevel::DENY;
    }
  }

  // All DENY checks are passed.

  // Check whether the server/renderer is running as RunAs.
  if (type == SERVER || type == RENDERER) {
    // It's ok to do this check after RevertToSelf, as it's a process token
    // and also its handle was opened before.
    if (IsDifferentUser(process_token.get())) {
      // Run in RESTRICTED level in order to prevent the process from running
      // too long in another user's desktop.
      return RunLevel::RESTRICTED;
    }
  }

  return RunLevel::NORMAL;

#else

  // Linux or Mac
  if (type == SERVER || type == RENDERER) {
    if (::geteuid() == 0) {
      // This process is started by root, or the executable is setuid to root.

      // TODO(yusukes): It would be better to add 'SAFE' run-level which
      //  prohibits all mutable operations to local resources and return the
      //  level after calling chroot("/somewhere/safe"), setgid("nogroup"),
      //  and setuid("nobody") here. This is because many novice Linux users
      //  tend to login to their desktop as root.

      return RunLevel::DENY;
    }
    if (::getuid() == 0) {
      // The executable is setuided to non-root and is started by root user?
      // This is unexpected. Returns DENY.
      return RunLevel::DENY;
    }
    return RunLevel::NORMAL;
  }

  // type is 'CLIENT'
  if (::geteuid() == 0 || ::getuid() == 0) {
    // When mozc.so is loaded into a privileged process, deny clients to use
    // dictionary_tool and config_dialog.
    return RunLevel::DENY;
  }

  return RunLevel::NORMAL;

#endif
}

bool RunLevel::IsProcessInJob() {
#ifdef OS_WIN
  // Check to see if we're in a job where
  // we can't create a child in our sandbox

  JOBOBJECT_EXTENDED_LIMIT_INFORMATION JobExtLimitInfo;
  // Get the job information of the current process
  if (!::QueryInformationJobObject(
          NULL, JobObjectExtendedLimitInformation,
          &JobExtLimitInfo, sizeof(JobExtLimitInfo), NULL)) {
    return false;
  }

  // Check to see if we can break away from the current job
  if (JobExtLimitInfo.BasicLimitInformation.LimitFlags &
      (JOB_OBJECT_LIMIT_BREAKAWAY_OK |
       JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)) {
    // We're in a job, but it allows to break away.
    return false;
  }

  return true;
#else
  return false;
#endif
}

bool RunLevel::IsElevatedByUAC() {
#ifdef OS_WIN
  // Get process token
  HANDLE hProcessToken = NULL;
  if (!::OpenProcessToken(::GetCurrentProcess(),
                          TOKEN_QUERY | TOKEN_QUERY_SOURCE,
                          &hProcessToken)) {
    return false;
  }

  ScopedHandle process_token(hProcessToken);
  return mozc::IsElevatedByUAC(process_token.get());
#else
  return false;
#endif
}

bool RunLevel::SetElevatedProcessDisabled(bool disable) {
#ifdef OS_WIN
  HKEY key = 0;
  LONG result = ::RegCreateKeyExW(HKEY_CURRENT_USER,
                                  kElevatedProcessDisabledKey,
                                  0,
                                  NULL,
                                  0,
                                  KEY_WRITE,
                                  NULL,
                                  &key,
                                  NULL);

  if (ERROR_SUCCESS != result) {
    return false;
  }

  const DWORD value = disable ? 1 : 0;
  result = ::RegSetValueExW(key,
                            kElevatedProcessDisabledName,
                            0,
                            REG_DWORD,
                            reinterpret_cast<const BYTE *>(&value),
                            sizeof(value));
  ::RegCloseKey(key);

  return ERROR_SUCCESS == result;
#else
  return false;
#endif
}

bool RunLevel::GetElevatedProcessDisabled() {
#ifdef OS_WIN
  HKEY  key = 0;
  LONG result = ::RegOpenKeyExW(HKEY_CURRENT_USER,
                                kElevatedProcessDisabledKey,
                                NULL,
                                KEY_READ,
                                &key);
  if (ERROR_SUCCESS != result) {
    return false;
  }

  DWORD value = 0;
  DWORD value_size = sizeof(value);
  DWORD value_type = 0;
  result = ::RegQueryValueEx(key,
                             kElevatedProcessDisabledName,
                             NULL,
                             &value_type,
                             reinterpret_cast<BYTE *>(&value),
                             &value_size);
  ::RegCloseKey(key);

  if (ERROR_SUCCESS != result ||
      value_type != REG_DWORD ||
      value_size != sizeof(value)) {
    return false;
  }

  return value > 0;
#else
  return false;
#endif
}
}  // namespace mozc
