curtain_mode_linux.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/host/curtain_mode.h"
  5. #include "base/callback.h"
  6. #include "base/memory/ptr_util.h"
  7. #include "base/task/single_thread_task_runner.h"
  8. #include "remoting/base/logging.h"
  9. #include "remoting/host/client_session_control.h"
  10. #include "ui/gfx/x/connection.h"
  11. #include "ui/gfx/x/future.h"
  12. #include "ui/gfx/x/xinput.h"
  13. #include "ui/gfx/x/xproto_types.h"
  14. namespace remoting {
  15. class CurtainModeLinux : public CurtainMode {
  16. public:
  17. CurtainModeLinux();
  18. CurtainModeLinux(const CurtainModeLinux&) = delete;
  19. CurtainModeLinux& operator=(const CurtainModeLinux&) = delete;
  20. // Overriden from CurtainMode.
  21. bool Activate() override;
  22. private:
  23. // Returns true if the host is running under a virtual session.
  24. bool IsVirtualSession();
  25. };
  26. CurtainModeLinux::CurtainModeLinux() = default;
  27. bool CurtainModeLinux::Activate() {
  28. // We can't curtain the session in run-time in Linux.
  29. // Either the session is running in a virtual session (i.e. always curtained),
  30. // or it is attached to the physical console (i.e. impossible to curtain).
  31. if (!IsVirtualSession()) {
  32. LOG(ERROR) << "Curtain-mode is not supported when running on non-virtual "
  33. "X server";
  34. return false;
  35. }
  36. return true;
  37. }
  38. bool CurtainModeLinux::IsVirtualSession() {
  39. // Try to identify a virtual session. Since there's no way to tell from the
  40. // vendor string, we check for known virtual input devices.
  41. // TODO(rmsousa): Find a similar way to determine that the *output* is secure.
  42. x11::Connection* connection = x11::Connection::Get();
  43. if (!connection->xinput().present()) {
  44. // If XInput is not available, assume it is not a virtual session.
  45. LOG(ERROR) << "X Input extension not available";
  46. return false;
  47. }
  48. auto devices = connection->xinput().ListInputDevices().Sync();
  49. if (!devices) {
  50. LOG(ERROR) << "ListInputDevices failed";
  51. return false;
  52. }
  53. bool found_xvfb_mouse = false;
  54. bool found_xvfb_keyboard = false;
  55. bool found_crd_void_input = false;
  56. bool found_other_devices = false;
  57. for (size_t i = 0; i < devices->devices.size(); i++) {
  58. const auto& device_info = devices->devices[i];
  59. const std::string& name = devices->names[i].name;
  60. if (device_info.device_use == x11::Input::DeviceUse::IsXExtensionPointer) {
  61. if (name == "Xvfb mouse") {
  62. found_xvfb_mouse = true;
  63. } else if (name == "Chrome Remote Desktop Input") {
  64. found_crd_void_input = true;
  65. } else if (name != "Virtual core XTEST pointer") {
  66. found_other_devices = true;
  67. HOST_LOG << "Non-virtual mouse found: " << name;
  68. }
  69. } else if (device_info.device_use ==
  70. x11::Input::DeviceUse::IsXExtensionKeyboard) {
  71. if (name == "Xvfb keyboard") {
  72. found_xvfb_keyboard = true;
  73. } else if (name != "Virtual core XTEST keyboard") {
  74. found_other_devices = true;
  75. HOST_LOG << "Non-virtual keyboard found: " << name;
  76. }
  77. } else if (device_info.device_use == x11::Input::DeviceUse::IsXPointer) {
  78. if (name != "Virtual core pointer") {
  79. found_other_devices = true;
  80. HOST_LOG << "Non-virtual mouse found: " << name;
  81. }
  82. } else if (device_info.device_use == x11::Input::DeviceUse::IsXKeyboard) {
  83. if (name != "Virtual core keyboard") {
  84. found_other_devices = true;
  85. HOST_LOG << "Non-virtual keyboard found: " << name;
  86. }
  87. } else {
  88. found_other_devices = true;
  89. HOST_LOG << "Non-virtual device found: " << name;
  90. }
  91. }
  92. return ((found_xvfb_mouse && found_xvfb_keyboard) || found_crd_void_input) &&
  93. !found_other_devices;
  94. }
  95. // static
  96. std::unique_ptr<CurtainMode> CurtainMode::Create(
  97. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
  98. scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
  99. base::WeakPtr<ClientSessionControl> client_session_control) {
  100. return base::WrapUnique(new CurtainModeLinux());
  101. }
  102. } // namespace remoting