VNC authentication works, although there is no UI for adding passwords

yet. Direct database manipulation is required for now.
This commit is contained in:
Simo Kinnunen
2015-10-13 03:14:18 +09:00
parent a902c66131
commit 5b5520b705
8 changed files with 332 additions and 32 deletions

View File

@@ -8,6 +8,9 @@ var uuid = require('node-uuid')
var jpeg = require('jpeg-turbo')
var logger = require('../../../../util/logger')
var grouputil = require('../../../../util/grouputil')
var wire = require('../../../../wire')
var wireutil = require('../../../../wire/util')
var lifecycle = require('../../../../util/lifecycle')
var VncServer = require('./util/server')
@@ -15,11 +18,75 @@ var VncConnection = require('./util/connection')
var PointerTranslator = require('./util/pointertranslator')
module.exports = syrup.serial()
.dependency(require('../../support/router'))
.dependency(require('../../support/push'))
.dependency(require('../screen/stream'))
.dependency(require('../touch'))
.define(function(options, screenStream, touch) {
.dependency(require('../group'))
.dependency(require('../solo'))
.define(function(options, router, push, screenStream, touch, group, solo) {
var log = logger.createLogger('device:plugins:vnc')
function vncAuthHandler(data) {
log.info('VNC authentication attempt using "%s"', data.fingerprint)
var resolver = Promise.defer()
function notify() {
group.get()
.then(function(currentGroup) {
push.send([
solo.channel
, wireutil.envelope(new wire.JoinGroupByVncAuthResponseMessage(
options.serial
, data.response.toString('hex')
, currentGroup.group
))
])
})
.catch(grouputil.NoGroupError, function() {
push.send([
solo.channel
, wireutil.envelope(new wire.JoinGroupByVncAuthResponseMessage(
options.serial
, data.response.toString('hex')
))
])
})
}
function joinListener(newGroup, identifier) {
if (!data.response.equals(new Buffer(identifier || '', 'hex'))) {
resolver.reject(new Error('Someone else took the device'))
}
}
function autojoinListener(identifier, joined) {
if (data.response.equals(new Buffer(identifier, 'hex'))) {
if (joined) {
resolver.resolve()
}
else {
resolver.reject(new Error('Device is already in use'))
}
}
}
group.on('join', joinListener)
group.on('autojoin', autojoinListener)
router.on(wire.VncAuthResponsesUpdatedMessage, notify)
notify()
return resolver.promise
.timeout(5000)
.finally(function() {
group.removeListener('join', joinListener)
group.removeListener('autojoin', autojoinListener)
router.removeListener(wire.VncAuthResponsesUpdatedMessage, notify)
})
}
function createServer() {
log.info('Starting VNC server on port %d', options.vncPort)
@@ -27,6 +94,11 @@ module.exports = syrup.serial()
name: options.serial
, width: options.vncInitialSize[0]
, height: options.vncInitialSize[1]
, security: [{
type: VncConnection.SECURITY_VNC
, challenge: new Buffer(16).fill(0)
, auth: vncAuthHandler
}]
}
var vnc = new VncServer(net.createServer({
@@ -57,6 +129,8 @@ module.exports = syrup.serial()
return createServer()
.then(function(vnc) {
vnc.on('connection', function(conn) {
log.info('New VNC connection from %s', conn.conn.remoteAddress)
var id = util.format('vnc-%s', uuid.v4())
var connState = {
@@ -89,23 +163,6 @@ module.exports = syrup.serial()
touch.touchCommit()
})
function vncStartListener(frameProducer) {
return new Promise(function(resolve/*, reject*/) {
connState.frameWidth = frameProducer.banner.virtualWidth
connState.frameHeight = frameProducer.banner.virtualHeight
resolve()
})
}
function vncFrameListener(frame) {
return new Promise(function(resolve/*, reject*/) {
connState.lastFrame = frame
connState.lastFrameTime = Date.now()
maybeSendFrame()
resolve()
})
}
function maybeSendFrame() {
if (!connState.updateRequests) {
return
@@ -142,6 +199,27 @@ module.exports = syrup.serial()
connState.sentFrameTime = connState.lastFrameTime
}
function vncStartListener(frameProducer) {
return new Promise(function(resolve/*, reject*/) {
connState.frameWidth = frameProducer.banner.virtualWidth
connState.frameHeight = frameProducer.banner.virtualHeight
resolve()
})
}
function vncFrameListener(frame) {
return new Promise(function(resolve/*, reject*/) {
connState.lastFrame = frame
connState.lastFrameTime = Date.now()
maybeSendFrame()
resolve()
})
}
function groupLeaveListener() {
conn.end()
}
conn.on('authenticated', function() {
screenStream.updateProjection(
options.vncInitialSize[0], options.vncInitialSize[1])
@@ -157,7 +235,7 @@ module.exports = syrup.serial()
})
conn.on('formatchange', function(format) {
var same = os.endianness() == 'BE' == format.bigEndianFlag
var same = os.endianness() === 'BE' === format.bigEndianFlag
switch (format.bitsPerPixel) {
case 8:
connState.frameConfig = {
@@ -191,7 +269,14 @@ module.exports = syrup.serial()
conn.on('close', function() {
screenStream.broadcastSet.remove(id)
group.removeListener('leave', groupLeaveListener)
})
conn.on('userActivity', function() {
group.keepalive()
})
group.on('leave', groupLeaveListener)
})
lifecycle.observe(function() {