Mon 21 Jul 22:43:21 CEST 2025

This commit is contained in:
sbosse 2025-07-21 23:06:32 +02:00
parent c0593d1b21
commit 9d1f5033fa

View 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);