summaryrefslogtreecommitdiffstats
path: root/remoting/host/curtain_mode_linux.cc
diff options
context:
space:
mode:
authorrmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-09 04:47:20 +0000
committerrmsousa@chromium.org <rmsousa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-09 04:47:20 +0000
commit3e50a33f88422dc58973b17980b9103728790c70 (patch)
treed52862a2a7bd9994cafedca92ccc15eb7d0d9ea2 /remoting/host/curtain_mode_linux.cc
parentec8b63ba024c43764acd3a67618405d9fed7cda3 (diff)
downloadchromium_src-3e50a33f88422dc58973b17980b9103728790c70.zip
chromium_src-3e50a33f88422dc58973b17980b9103728790c70.tar.gz
chromium_src-3e50a33f88422dc58973b17980b9103728790c70.tar.bz2
Linux curtain mode implementation.
The basic design is to check if the host is running on VFB - if it is, it's trivially curtained, so we allow the remote clients. If it's not running on VFB, we assume it's running in the console, and we can't curtain it, so we just reject all remote clients. Checking for VFB is done in an indirect way - we check that the Xvfb virtual input devices are present, and that there are no other input devices, aside from possibly the xtest ones. BUG=146716 Review URL: https://chromiumcodereview.appspot.com/11092011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@160794 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/curtain_mode_linux.cc')
-rw-r--r--remoting/host/curtain_mode_linux.cc89
1 files changed, 84 insertions, 5 deletions
diff --git a/remoting/host/curtain_mode_linux.cc b/remoting/host/curtain_mode_linux.cc
index 5c3f269..61a3d97 100644
--- a/remoting/host/curtain_mode_linux.cc
+++ b/remoting/host/curtain_mode_linux.cc
@@ -4,28 +4,107 @@
#include "remoting/host/curtain_mode.h"
+#include <X11/extensions/XInput.h>
+
+#include "base/callback.h"
#include "base/logging.h"
namespace remoting {
class CurtainModeLinux : public CurtainMode {
public:
- CurtainModeLinux() {}
+ CurtainModeLinux(const base::Closure& on_session_activate,
+ const base::Closure& on_error);
+
// Overriden from CurtainMode.
- virtual void SetActivated(bool activated) OVERRIDE {
- NOTIMPLEMENTED();
- }
+ virtual void SetActivated(bool activated) OVERRIDE;
private:
+ // Returns true if the host is running under an Xvfb session.
+ bool IsXvfbSession();
+
+ base::Closure on_session_activate_;
+ base::Closure on_error_;
+
DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux);
};
+CurtainModeLinux::CurtainModeLinux(const base::Closure& on_session_activate,
+ const base::Closure& on_error)
+ : on_session_activate_(on_session_activate),
+ on_error_(on_error) {
+}
+
+bool CurtainModeLinux::IsXvfbSession() {
+ // Try to identify an Xvfb session. There's no way to query what X server we
+ // are running under, so we check for the Xvfb input devices.
+ // TODO(rmsousa): Find a similar way to determine that the *output* is secure.
+ Display* display = XOpenDisplay(NULL);
+ int opcode, event, error;
+ if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) {
+ // If XInput is not available, assume it is not an Xvfb session.
+ LOG(ERROR) << "X Input extension not available: " << error;
+ XCloseDisplay(display);
+ return false;
+ }
+ int num_devices;
+ XDeviceInfo* devices;
+ bool found_xvfb_mouse = false;
+ bool found_xvfb_keyboard = false;
+ bool found_other_devices = false;
+ devices = XListInputDevices(display, &num_devices);
+ for (int i = 0; i < num_devices; i++) {
+ XDeviceInfo* device_info = &devices[i];
+ if (device_info->use == IsXExtensionPointer) {
+ if (strcmp(device_info->name, "Xvfb mouse") == 0) {
+ found_xvfb_mouse = true;
+ } else if (strcmp(device_info->name, "Virtual core XTEST pointer") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXExtensionKeyboard) {
+ if (strcmp(device_info->name, "Xvfb keyboard") == 0) {
+ found_xvfb_keyboard = true;
+ } else if (strcmp(device_info->name,
+ "Virtual core XTEST keyboard") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXPointer) {
+ if (strcmp(device_info->name, "Virtual core pointer") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXKeyboard) {
+ if (strcmp(device_info->name, "Virtual core keyboard") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
+ }
+ } else {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb device found: " << device_info->name;
+ }
+ }
+ XFreeDeviceList(devices);
+ XCloseDisplay(display);
+ return found_xvfb_mouse && found_xvfb_keyboard && !found_other_devices;
+}
+
+void CurtainModeLinux::SetActivated(bool activated) {
+ // We can't curtain the session in run-time in Linux.
+ // Either the session is running on Xvfb (i.e. always curtained), or it is
+ // attached to the physical console (i.e. impossible to curtain).
+ if (activated && !IsXvfbSession()) {
+ on_error_.Run();
+ }
+}
+
// static
scoped_ptr<CurtainMode> CurtainMode::Create(
const base::Closure& on_session_activate,
const base::Closure& on_error) {
return scoped_ptr<CurtainMode>(
- new CurtainModeLinux());
+ new CurtainModeLinux(on_session_activate, on_error));
}
} // namespace remoting