Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
c0593d1b21
commit
9d1f5033fa
193
js/x11/examples/vncviewer/rfbserver.js
Normal file
193
js/x11/examples/vncviewer/rfbserver.js
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
"use strict";
|
||||||
|
var util = require('util');
|
||||||
|
var net = require('net');
|
||||||
|
var PackStream = require('./unpackstream');
|
||||||
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
var rfb = require('./constants');
|
||||||
|
|
||||||
|
function RfbServer(stream, params)
|
||||||
|
{
|
||||||
|
EventEmitter.call(this);
|
||||||
|
this.params = params;
|
||||||
|
var serv = this;
|
||||||
|
serv.stream = stream;
|
||||||
|
serv.pack_stream = new PackStream();
|
||||||
|
serv.pack_stream.on('data', function( data ) {
|
||||||
|
serv.stream.write(data);
|
||||||
|
});
|
||||||
|
stream.on('data', function( data ) {
|
||||||
|
serv.pack_stream.write(data);
|
||||||
|
});
|
||||||
|
serv.writeServerVersion();
|
||||||
|
serv.params = {};
|
||||||
|
serv.params.password = 'tetris';
|
||||||
|
}
|
||||||
|
util.inherits(RfbServer, EventEmitter);
|
||||||
|
|
||||||
|
RfbServer.prototype.writeServerVersion = function()
|
||||||
|
{
|
||||||
|
var serv = this;
|
||||||
|
this.stream.write(rfb.versionstring.V3_008);
|
||||||
|
this.pack_stream.get(12, function(buf) {
|
||||||
|
serv.emit('clientversion', buf.toString('ascii'));
|
||||||
|
console.log(['client version', buf]);
|
||||||
|
serv.writeSecurityTypes();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RfbServer.prototype.writeSecurityTypes = function()
|
||||||
|
{
|
||||||
|
console.log("RfbServer.prototype.writeSecurityTypes");
|
||||||
|
var serv = this;
|
||||||
|
var sectypes = [rfb.security.VNC];
|
||||||
|
serv.pack_stream.pack('C', [sectypes.length]);
|
||||||
|
serv.pack_stream.flush();
|
||||||
|
for (var i=0; i < sectypes.length; ++i)
|
||||||
|
serv.pack_stream.pack('C', [sectypes[i]]);
|
||||||
|
serv.pack_stream.flush();
|
||||||
|
serv.pack_stream.unpack('C', function(cliSecType) {
|
||||||
|
serv.securityType = cliSecType[0];
|
||||||
|
serv.processSecurity();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RfbServer.prototype.processSecurity = function()
|
||||||
|
{
|
||||||
|
console.log("RfbServer.prototype.processSecurity");
|
||||||
|
var serv = this;
|
||||||
|
switch(serv.securityType)
|
||||||
|
{
|
||||||
|
case rfb.security.None:
|
||||||
|
console.log('not yet');
|
||||||
|
break;
|
||||||
|
case rfb.security.VNC:
|
||||||
|
// generate random 16 byte challenge
|
||||||
|
serv.challenge = new Buffer(16);
|
||||||
|
serv.challenge.write('1234567890abcdef');
|
||||||
|
console.log(['sending challenge', serv.challenge]);
|
||||||
|
serv.pack_stream.pack('a', [serv.challenge]).flush();
|
||||||
|
serv.pack_stream.get(16, function(clientResponseBuf)
|
||||||
|
{
|
||||||
|
var response = require('./d3des').response(serv.challenge, serv.params.password).toString('binary');
|
||||||
|
var clientResponse = clientResponseBuf.toString('binary');
|
||||||
|
console.log([response, clientResponse]);
|
||||||
|
if (response === clientResponse) {
|
||||||
|
serv.pack_stream.pack('L', [0]).flush();
|
||||||
|
serv.readClientInit();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
console.error('invalid password!');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RfbServer.prototype.readClientInit = function()
|
||||||
|
{
|
||||||
|
// TODO: read options, add 'disconnect others' code
|
||||||
|
var serv = this;
|
||||||
|
serv.pack_stream.unpack('C', function(isShared) {
|
||||||
|
console.log([isShared]);
|
||||||
|
serv.writeServerInit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RfbServer.prototype.writeServerInit = function()
|
||||||
|
{
|
||||||
|
var serv = this;
|
||||||
|
var title = 'Param-pam-pam';
|
||||||
|
serv.pack_stream.pack('SSCCCCSSSCCCxxxLa', [
|
||||||
|
800, //serv.width,
|
||||||
|
600, //serv.height,
|
||||||
|
32, //serv.bpp,
|
||||||
|
24, //serv.depth,
|
||||||
|
1, // bigEndien
|
||||||
|
1, // trueColor
|
||||||
|
255, // red max
|
||||||
|
255, // green
|
||||||
|
255, // blue
|
||||||
|
16, // red shift
|
||||||
|
8, // green
|
||||||
|
0, // blue
|
||||||
|
title.length,
|
||||||
|
title
|
||||||
|
]);
|
||||||
|
serv.pack_stream.flush();
|
||||||
|
serv.expectMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
function repeat(str, num)
|
||||||
|
{
|
||||||
|
var res = '';
|
||||||
|
for (var i=0; i < num; ++i)
|
||||||
|
res += str;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
RfbServer.prototype.expectMessage = function()
|
||||||
|
{
|
||||||
|
var serv = this;
|
||||||
|
serv.pack_stream.get(1, function(msgType) {
|
||||||
|
switch(msgType[0]) {
|
||||||
|
case rfb.clientMsgTypes.setPixelFormat:
|
||||||
|
case rfb.clientMsgTypes.fbUpdate:
|
||||||
|
var updateRequest = {};
|
||||||
|
serv.pack_stream.unpackTo(updateRequest, [
|
||||||
|
'C incremental',
|
||||||
|
'S width',
|
||||||
|
'S height',
|
||||||
|
'S x',
|
||||||
|
'S y'],
|
||||||
|
function() {
|
||||||
|
serv.emit('fbUpdate', updateRequest);
|
||||||
|
serv.expectMessage();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case rfb.clientMsgTypes.setEncodings:
|
||||||
|
serv.pack_stream.unpack('xS', function(numEnc)
|
||||||
|
{
|
||||||
|
serv.pack_stream.unpack(repeat('L', numEnc), function(res) {
|
||||||
|
serv.emit('setEncodings', res);
|
||||||
|
console.log(['setEncodings', res]);
|
||||||
|
serv.expectMessage();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case rfb.clientMsgTypes.pointerEvent:
|
||||||
|
serv.pack_stream.unpack('CSS', function(res) {
|
||||||
|
var pointerEvent = {
|
||||||
|
buttons: res[0],
|
||||||
|
x: res[1],
|
||||||
|
y: res[2]
|
||||||
|
};
|
||||||
|
serv.emit('pointer', pointerEvent);
|
||||||
|
console.log(['pointer', pointerEvent]);
|
||||||
|
serv.expectMessage();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case rfb.clientMsgTypes.keyEvent:
|
||||||
|
serv.pack_stream.unpack('CxxL', function(res) {
|
||||||
|
var keyEvent = {
|
||||||
|
isDown: res[0],
|
||||||
|
keysym: res[1]
|
||||||
|
};
|
||||||
|
serv.emit('key', keyEvent);
|
||||||
|
console.log(['key', keyEvent]);
|
||||||
|
serv.expectMessage();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case rfb.clientMsgTypes.cutText:
|
||||||
|
break;
|
||||||
|
console.log('Got message from client: ' + msgType[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var s = net.createServer(function(conn) {
|
||||||
|
var rfbserv = new RfbServer(conn);
|
||||||
|
});
|
||||||
|
s.listen(5910);
|
Loading…
Reference in New Issue
Block a user