From 95eb681bbb609c1fe6a7dace694afa6ed00cf4d3 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Tue, 20 May 2014 17:03:40 -0400 Subject: Support the "NOTUNNEL" tunnel type for TightVNC Previously, tight auth was supported without any support for tunnels, even the no-op tunnel. No, the no-op tunnel type is supported. --- include/rfb.js | 49 +++++++++++++++++++++++++++++++++++++++---------- include/util.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/include/rfb.js b/include/rfb.js index 3b748ba..75034ca 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -322,6 +322,7 @@ init_vars = function() { FBU.zlibs = []; // TIGHT zlib encoders mouse_buttonMask = 0; mouse_arr = []; + rfb_tightvnc = false; // Clear the per connection encoding stats for (i=0; i < encodings.length; i+=1) { @@ -775,23 +776,51 @@ init_msg = function() { updateState('SecurityResult'); return; case 16: // TightVNC Security Type - if (ws.rQwait("num tunnels", 4)) { return false; } - var numTunnels = ws.rQshift32(); - //console.log("Number of tunnels: "+numTunnels); - - rfb_tightvnc = true; + if (!rfb_tightvnc) { + // we haven't been through this before, so assume + // we need to check for tunnel support + if (ws.rQwait("num tunnels", 4)) { return false; } + var numTunnels = ws.rQshift32(); + //console.log("Number of tunnels: "+numTunnels); + + rfb_tightvnc = true; + + var clientSupportedTunnelTypes = { + 0: { vender: 'TGHT', signature: 'NOTUNNEL' } + }; + + if (numTunnels > 0) { + var serverSupportedTunnelTypes = {} + // receive tunnel capabilities + for (var i = 0; i < numTunnels; i++) { + if (ws.rQwait("tunnel " + i.toString() + " capability", 16)) { return false; } + + var cap_code = ws.rQshift32(); + var cap_vendor = ws.rQshiftStr(4); + var cap_signature = ws.rQshiftStr(8); + serverSupportedTunnelTypes[cap_code] = { vendor: cap_vendor, signature: cap_signature }; + } - if (numTunnels != 0) - { - fail("Protocol requested tunnels, not currently supported. numTunnels: " + numTunnels); - return; - } + // choose an auth type + for (var cap_code in clientSupportedTunnelTypes) { + if (serverSupportedTunnelTypes[cap_code] != undefined) { + // TODO(directxman12): convert capcode back to U32 + ws.send([0,0,0,cap_code]); + return; + } + } + + fail("No supported tunnel types"); + return; + } + } // otherwise, we've dealt with tunnels, so jump right into auth var clientSupportedTypes = { 'STDVNOAUTH__': 1, 'STDVVNCAUTH_': 2 }; + var serverSupportedTypes = []; if (ws.rQwait("sub auth count", 4)) { return false; } diff --git a/include/util.js b/include/util.js index 05c1ac3..ea14b5b 100644 --- a/include/util.js +++ b/include/util.js @@ -84,6 +84,47 @@ if (!Array.prototype.indexOf) }; } +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys +if (!Object.keys) { + Object.keys = (function () { + 'use strict'; + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; + + return function (obj) { + if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], prop, i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; + }; + }()); +} // // requestAnimationFrame shim with setTimeout fallback -- cgit v1.2.1