chromium/remoting/host/mac/permission_process_utils.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/mac/permission_process_utils.h"

#include <fcntl.h>

#include "base/command_line.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "remoting/host/mac/constants_mac.h"
#include "remoting/host/version.h"

namespace remoting::mac {

namespace {

base::FilePath GetHostExePath(HostMode mode) {
  // Path to the host bundle top directory.
  base::FilePath host_path(kHostBinaryPath);

  host_path = host_path.Append("Contents/MacOS");
  if (mode == HostMode::ME2ME) {
    return host_path.Append("remoting_me2me_host");
  }

  return host_path.Append(REMOTE_ASSISTANCE_HOST_BUNDLE_NAME)
      .Append("Contents/MacOS/remote_assistance_host");
}

bool CheckHostPermission(base::FilePath exe_path, std::string command_switch) {
  base::CommandLine cmdLine(exe_path);
  cmdLine.AppendSwitch(command_switch);

  // Redirect stdout to /dev/null, otherwise the child will inherit stdout from
  // the parent, possibly corrupting the native-messaging channels.
  // LaunchProcess() already redirects stdin to /dev/null, so no need to do it
  // here.
  base::ScopedFD null_fd(HANDLE_EINTR(open("/dev/null", O_WRONLY)));
  if (!null_fd.is_valid()) {
    PLOG(ERROR) << "Failed to open /dev/null";
    return false;
  }
  base::LaunchOptions options;
  options.disclaim_responsibility = true;
  options.fds_to_remap.push_back(std::make_pair(null_fd.get(), STDOUT_FILENO));
  base::Process process = base::LaunchProcess(cmdLine, options);
  if (!process.IsValid()) {
    PLOG(ERROR) << "Unable to launch host process";
    return false;
  }
  int exit_code;
  process.WaitForExit(&exit_code);
  LOG(INFO) << "Permission '" << command_switch << "' is "
            << ((exit_code == 0) ? "granted" : "denied");
  return exit_code == 0;
}

}  // namespace

bool CheckAccessibilityPermission(HostMode mode) {
  return CheckHostPermission(GetHostExePath(mode),
                             "check-accessibility-permission");
}

bool CheckScreenRecordingPermission(HostMode mode) {
  return CheckHostPermission(GetHostExePath(mode),
                             "check-screen-recording-permission");
}

}  // namespace remoting::mac