Commit 06a9ef0c authored by Joel Martin's avatar Joel Martin

Add View Only mode setting.

Resolve issue: https://github.com/kanaka/noVNC/pull/101

Based on proposal from @mightpenguin:
Matthew Balman <emperor@mightypenguin.org>

If view_only option is set then do not send mouse and keyboard events.
This is not a secure/enforced way to make a client view only. To
enforce view only at the server, most VNC servers support setting
a view only password.
parent c3a172b9
...@@ -131,6 +131,7 @@ Util.conf_defaults(conf, that, defaults, [ ...@@ -131,6 +131,7 @@ Util.conf_defaults(conf, that, defaults, [
['true_color', 'rw', 'bool', true, 'Request true color pixel data'], ['true_color', 'rw', 'bool', true, 'Request true color pixel data'],
['local_cursor', 'rw', 'bool', false, 'Request locally rendered cursor'], ['local_cursor', 'rw', 'bool', false, 'Request locally rendered cursor'],
['shared', 'rw', 'bool', true, 'Request shared mode'], ['shared', 'rw', 'bool', true, 'Request shared mode'],
['view_only', 'rw', 'bool', false, 'Disable client mouse/keyboard'],
['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'], ['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'],
['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'], ['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'],
...@@ -565,6 +566,9 @@ checkEvents = function() { ...@@ -565,6 +566,9 @@ checkEvents = function() {
keyPress = function(keysym, down) { keyPress = function(keysym, down) {
var arr; var arr;
if (conf.view_only) { return; } // View only, skip keyboard events
arr = keyEvent(keysym, down); arr = keyEvent(keysym, down);
arr = arr.concat(fbUpdateRequests()); arr = arr.concat(fbUpdateRequests());
ws.send(arr); ws.send(arr);
...@@ -586,9 +590,12 @@ mouseButton = function(x, y, down, bmask) { ...@@ -586,9 +590,12 @@ mouseButton = function(x, y, down, bmask) {
return; return;
} else { } else {
viewportDragging = false; viewportDragging = false;
ws.send(fbUpdateRequests()); // Force immediate redraw
} }
} }
if (conf.view_only) { return; } // View only, skip mouse events
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)) );
flushClient(); flushClient();
...@@ -611,6 +618,8 @@ mouseMove = function(x, y) { ...@@ -611,6 +618,8 @@ mouseMove = function(x, y) {
return; return;
} }
if (conf.view_only) { return; } // View only, skip mouse events
mouse_arr = mouse_arr.concat( mouse_arr = mouse_arr.concat(
pointerEvent(display.absX(x), display.absY(y)) ); pointerEvent(display.absX(x), display.absY(y)) );
}; };
...@@ -1556,7 +1565,7 @@ that.sendPassword = function(passwd) { ...@@ -1556,7 +1565,7 @@ that.sendPassword = function(passwd) {
}; };
that.sendCtrlAltDel = function() { that.sendCtrlAltDel = function() {
if (rfb_state !== "normal") { return false; } if (rfb_state !== "normal" || conf.view_only) { return false; }
Util.Info("Sending Ctrl-Alt-Del"); Util.Info("Sending Ctrl-Alt-Del");
var arr = []; var arr = [];
arr = arr.concat(keyEvent(0xFFE3, 1)); // Control arr = arr.concat(keyEvent(0xFFE3, 1)); // Control
...@@ -1572,7 +1581,7 @@ that.sendCtrlAltDel = function() { ...@@ -1572,7 +1581,7 @@ that.sendCtrlAltDel = function() {
// Send a key press. If 'down' is not specified then send a down key // Send a key press. If 'down' is not specified then send a down key
// followed by an up key. // followed by an up key.
that.sendKey = function(code, down) { that.sendKey = function(code, down) {
if (rfb_state !== "normal") { return false; } if (rfb_state !== "normal" || conf.view_only) { return false; }
var arr = []; var arr = [];
if (typeof down !== 'undefined') { if (typeof down !== 'undefined') {
Util.Info("Sending key code (" + (down ? "down" : "up") + "): " + code); Util.Info("Sending key code (" + (down ? "down" : "up") + "): " + code);
......
...@@ -52,6 +52,7 @@ load: function() { ...@@ -52,6 +52,7 @@ load: function() {
UI.initSetting('true_color', true); UI.initSetting('true_color', true);
UI.initSetting('cursor', false); UI.initSetting('cursor', false);
UI.initSetting('shared', true); UI.initSetting('shared', true);
UI.initSetting('view_only', false);
UI.initSetting('connectTimeout', 2); UI.initSetting('connectTimeout', 2);
UI.initSetting('path', ''); UI.initSetting('path', '');
...@@ -252,6 +253,7 @@ toggleSettingsPanel: function() { ...@@ -252,6 +253,7 @@ toggleSettingsPanel: function() {
} }
UI.updateSetting('clip'); UI.updateSetting('clip');
UI.updateSetting('shared'); UI.updateSetting('shared');
UI.updateSetting('view_only');
UI.updateSetting('connectTimeout'); UI.updateSetting('connectTimeout');
UI.updateSetting('path'); UI.updateSetting('path');
UI.updateSetting('stylesheet'); UI.updateSetting('stylesheet');
...@@ -292,6 +294,7 @@ settingsApply: function() { ...@@ -292,6 +294,7 @@ settingsApply: function() {
} }
UI.saveSetting('clip'); UI.saveSetting('clip');
UI.saveSetting('shared'); UI.saveSetting('shared');
UI.saveSetting('view_only');
UI.saveSetting('connectTimeout'); UI.saveSetting('connectTimeout');
UI.saveSetting('path'); UI.saveSetting('path');
UI.saveSetting('stylesheet'); UI.saveSetting('stylesheet');
...@@ -404,6 +407,7 @@ updateVisualState: function() { ...@@ -404,6 +407,7 @@ updateVisualState: function() {
$D('noVNC_cursor').disabled = true; $D('noVNC_cursor').disabled = true;
} }
$D('noVNC_shared').disabled = connected; $D('noVNC_shared').disabled = connected;
$D('noVNC_view_only').disabled = connected;
$D('noVNC_connectTimeout').disabled = connected; $D('noVNC_connectTimeout').disabled = connected;
$D('noVNC_path').disabled = connected; $D('noVNC_path').disabled = connected;
...@@ -464,6 +468,7 @@ connect: function() { ...@@ -464,6 +468,7 @@ connect: function() {
UI.rfb.set_true_color(UI.getSetting('true_color')); UI.rfb.set_true_color(UI.getSetting('true_color'));
UI.rfb.set_local_cursor(UI.getSetting('cursor')); UI.rfb.set_local_cursor(UI.getSetting('cursor'));
UI.rfb.set_shared(UI.getSetting('shared')); UI.rfb.set_shared(UI.getSetting('shared'));
UI.rfb.set_view_only(UI.getSetting('view_only'));
UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout')); UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout'));
UI.rfb.connect(host, port, password, path); UI.rfb.connect(host, port, password, path);
......
...@@ -118,8 +118,9 @@ ...@@ -118,8 +118,9 @@
<li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li> <li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li>
<li><input id="noVNC_true_color" type="checkbox" checked> True Color</li> <li><input id="noVNC_true_color" type="checkbox" checked> True Color</li>
<li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li> <li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li>
<li><input id="noVNC_clip" type="checkbox"> Clip to window</li> <li><input id="noVNC_clip" type="checkbox"> Clip to Window</li>
<li><input id="noVNC_shared" type="checkbox"> Shared Mode</li> <li><input id="noVNC_shared" type="checkbox"> Shared Mode</li>
<li><input id="noVNC_view_only" type="checkbox"> View Only</li>
<li><input id="noVNC_connectTimeout" type="input"> Connect Timeout (s)</li> <li><input id="noVNC_connectTimeout" type="input"> Connect Timeout (s)</li>
<li><input id="noVNC_path" type="input"> Path</li> <li><input id="noVNC_path" type="input"> Path</li>
<hr> <hr>
......
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
'true_color': WebUtil.getQueryVar('true_color', true), 'true_color': WebUtil.getQueryVar('true_color', true),
'local_cursor': WebUtil.getQueryVar('cursor', true), 'local_cursor': WebUtil.getQueryVar('cursor', true),
'shared': WebUtil.getQueryVar('shared', true), 'shared': WebUtil.getQueryVar('shared', true),
'view_only': WebUtil.getQueryVar('view_only', false),
'updateState': updateState, 'updateState': updateState,
'onPasswordRequired': passwordRequired}); 'onPasswordRequired': passwordRequired});
rfb.connect(host, port, password, path); rfb.connect(host, port, password, path);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment