re-implement binrect protocol
pretty easy since we can just subclass guac
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
import * as msgpack from 'msgpackr';
|
import * as msgpack from 'msgpackr';
|
||||||
import { CollabVMProtocolMessage, CollabVMProtocolMessageType } from '@cvmts/collab-vm-1.2-binary-protocol';
|
import { CollabVMProtocolMessage, CollabVMProtocolMessageType } from '@cvmts/collab-vm-1.2-binary-protocol';
|
||||||
|
import { GuacamoleProtocol } from './GuacamoleProtocol.js';
|
||||||
|
|
||||||
// TODO: reimplement binrects protocol
|
import { ScreenRect } from './Protocol';
|
||||||
// we can just create/proxy a GuacamoleProtocol manually,
|
|
||||||
// and for the rects do our own thing
|
export class BinRectsProtocol extends GuacamoleProtocol {
|
||||||
|
sendScreenUpdate(rect: ScreenRect): void {
|
||||||
|
let bmsg: CollabVMProtocolMessage = {
|
||||||
|
type: CollabVMProtocolMessageType.rect,
|
||||||
|
rect: rect
|
||||||
|
};
|
||||||
|
|
||||||
|
this.user?.socket.sendBinary(msgpack.encode(bmsg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
|
|
||||||
this.clients.splice(clientIndex, 1);
|
this.clients.splice(clientIndex, 1);
|
||||||
|
|
||||||
|
user.protocol.dispose();
|
||||||
|
|
||||||
this.logger.info(`Disconnect From ${user.IP.address}${user.username ? ` with username ${user.username}` : ''}`);
|
this.logger.info(`Disconnect From ${user.IP.address}${user.username ? ` with username ${user.username}` : ''}`);
|
||||||
if (!user.username) return;
|
if (!user.username) return;
|
||||||
if (this.TurnQueue.toArray().indexOf(user) !== -1) {
|
if (this.TurnQueue.toArray().indexOf(user) !== -1) {
|
||||||
@@ -273,9 +275,9 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
// Set rank
|
// Set rank
|
||||||
user.rank = res.rank;
|
user.rank = res.rank;
|
||||||
if (user.rank === Rank.Admin) {
|
if (user.rank === Rank.Admin) {
|
||||||
user.sendMsg(cvm.guacEncode('admin', '0', '1'));
|
user.protocol.sendAdminLoginResponse(true, undefined);
|
||||||
} else if (user.rank === Rank.Moderator) {
|
} else if (user.rank === Rank.Moderator) {
|
||||||
user.sendMsg(cvm.guacEncode('admin', '0', '3', this.ModPerms.toString()));
|
user.protocol.sendAdminLoginResponse(true, this.ModPerms);
|
||||||
}
|
}
|
||||||
this.clients.forEach((c) => c.sendMsg(cvm.guacEncode('adduser', '1', user.username!, user.rank.toString())));
|
this.clients.forEach((c) => c.sendMsg(cvm.guacEncode('adduser', '1', user.username!, user.rank.toString())));
|
||||||
} else {
|
} else {
|
||||||
@@ -303,12 +305,11 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
for (let cap of capability) {
|
for (let cap of capability) {
|
||||||
switch (cap) {
|
switch (cap) {
|
||||||
// binary 1.0 (msgpack rects)
|
// binary 1.0 (msgpack rects)
|
||||||
// TODO: re-enable once binary1.0 is enabled
|
|
||||||
case 'bin':
|
case 'bin':
|
||||||
this.logger.info('Binary 1.0 protocol is currently disabled for refactoring');
|
user.Capabilities.bin = true;
|
||||||
//user.Capabilities.bin = true;
|
user.protocol.dispose();
|
||||||
//user.protocol = TheProtocolManager.createProtocol('binary1', user);
|
user.protocol = TheProtocolManager.createProtocol('binary1', user);
|
||||||
//user.protocol.setHandler(this as IProtocolHandlers);
|
user.protocol.setHandler(this as IProtocolHandlers);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -513,12 +514,12 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
|
|
||||||
if (pwdHash === this.Config.collabvm.adminpass) {
|
if (pwdHash === this.Config.collabvm.adminpass) {
|
||||||
user.rank = Rank.Admin;
|
user.rank = Rank.Admin;
|
||||||
user.sendMsg(cvm.guacEncode('admin', '0', '1'));
|
user.protocol.sendAdminLoginResponse(true, undefined);
|
||||||
} else if (this.Config.collabvm.moderatorEnabled && pwdHash === this.Config.collabvm.modpass) {
|
} else if (this.Config.collabvm.moderatorEnabled && pwdHash === this.Config.collabvm.modpass) {
|
||||||
user.rank = Rank.Moderator;
|
user.rank = Rank.Moderator;
|
||||||
user.sendMsg(cvm.guacEncode('admin', '0', '3', this.ModPerms.toString()));
|
user.protocol.sendAdminLoginResponse(true, this.ModPerms);
|
||||||
} else {
|
} else {
|
||||||
user.sendMsg(cvm.guacEncode('admin', '0', '0'));
|
user.protocol.sendAdminLoginResponse(false, undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,14 +527,22 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
await this.SendFullScreenWithSize(user);
|
await this.SendFullScreenWithSize(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clients.forEach((c) => c.sendMsg(cvm.guacEncode('adduser', '1', user.username!, user.rank.toString())));
|
// Update rank
|
||||||
|
this.clients.forEach((c) =>
|
||||||
|
c.protocol.sendAddUser([
|
||||||
|
{
|
||||||
|
username: user.username!,
|
||||||
|
rank: user.rank
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAdminMonitor(user: User, node: string, command: string) {
|
async onAdminMonitor(user: User, node: string, command: string) {
|
||||||
if (user.rank !== Rank.Admin) return;
|
if (user.rank !== Rank.Admin) return;
|
||||||
if (node !== this.Config.collabvm.node) return;
|
if (node !== this.Config.collabvm.node) return;
|
||||||
let output = await this.VM.MonitorCommand(command);
|
let output = await this.VM.MonitorCommand(command);
|
||||||
user.sendMsg(cvm.guacEncode('admin', '2', String(output)));
|
user.protocol.sendAdminMonitorResponse(String(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdminRestore(user: User, node: string): void {
|
onAdminRestore(user: User, node: string): void {
|
||||||
@@ -605,7 +614,7 @@ export default class CollabVMServer implements IProtocolHandlers {
|
|||||||
if (user.rank !== Rank.Admin && (user.rank !== Rank.Moderator || !this.Config.collabvm.moderatorPermissions.grabip)) return;
|
if (user.rank !== Rank.Admin && (user.rank !== Rank.Moderator || !this.Config.collabvm.moderatorPermissions.grabip)) return;
|
||||||
let target = this.clients.find((c) => c.username === username);
|
let target = this.clients.find((c) => c.username === username);
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
user.sendMsg(cvm.guacEncode('admin', '19', username, target.IP.address));
|
user.protocol.sendAdminIPResponse(username, target.IP.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdminBypassTurn(user: User): void {
|
onAdminBypassTurn(user: User): void {
|
||||||
|
|||||||
@@ -11,12 +11,17 @@ export class GuacamoleProtocol implements IProtocol {
|
|||||||
name: 'CVMTS.GuacamoleProtocol'
|
name: 'CVMTS.GuacamoleProtocol'
|
||||||
});
|
});
|
||||||
|
|
||||||
private user: User | null = null;
|
protected user: User | null = null;
|
||||||
|
|
||||||
init(u: User): void {
|
init(u: User): void {
|
||||||
this.user = u;
|
this.user = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
this.user = null;
|
||||||
|
this.handlers = null;
|
||||||
|
}
|
||||||
|
|
||||||
setHandler(handlers: IProtocolHandlers): void {
|
setHandler(handlers: IProtocolHandlers): void {
|
||||||
this.handlers = handlers;
|
this.handlers = handlers;
|
||||||
}
|
}
|
||||||
@@ -237,6 +242,26 @@ export class GuacamoleProtocol implements IProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendAdminLoginResponse(ok: boolean, modPerms: number | undefined): void {
|
||||||
|
if (ok) {
|
||||||
|
if (modPerms == undefined) {
|
||||||
|
this.user?.sendMsg(cvm.guacEncode('admin', '0', '1'));
|
||||||
|
} else {
|
||||||
|
this.user?.sendMsg(cvm.guacEncode('admin', '0', '3', modPerms.toString()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.user?.sendMsg(cvm.guacEncode('admin', '0', '0'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendAdminMonitorResponse(output: string): void {
|
||||||
|
this.user?.sendMsg(cvm.guacEncode('admin', '2', output));
|
||||||
|
}
|
||||||
|
|
||||||
|
sendAdminIPResponse(username: string, ip: string): void {
|
||||||
|
this.user?.sendMsg(cvm.guacEncode('admin', '19', username, ip));
|
||||||
|
}
|
||||||
|
|
||||||
sendChatMessage(username: string, message: string): void {
|
sendChatMessage(username: string, message: string): void {
|
||||||
this.user?.sendMsg(cvm.guacEncode('chat', username, message));
|
this.user?.sendMsg(cvm.guacEncode('chat', username, message));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ export interface IProtocolHandlers {
|
|||||||
// Abstracts away all of the CollabVM protocol details
|
// Abstracts away all of the CollabVM protocol details
|
||||||
export interface IProtocol {
|
export interface IProtocol {
|
||||||
init(u: User): void;
|
init(u: User): void;
|
||||||
|
dispose(): void;
|
||||||
|
|
||||||
// Sets handler object.
|
// Sets handler object.
|
||||||
setHandler(handlers: IProtocolHandlers): void;
|
setHandler(handlers: IProtocolHandlers): void;
|
||||||
@@ -98,6 +99,10 @@ export interface IProtocol {
|
|||||||
|
|
||||||
sendLoginResponse(ok: boolean, message: string | undefined): void;
|
sendLoginResponse(ok: boolean, message: string | undefined): void;
|
||||||
|
|
||||||
|
sendAdminLoginResponse(ok: boolean, modPerms: number | undefined): void;
|
||||||
|
sendAdminMonitorResponse(output: string): void;
|
||||||
|
sendAdminIPResponse(username: string, ip: string): void;
|
||||||
|
|
||||||
sendChatMessage(username: '' | string, message: string): void;
|
sendChatMessage(username: '' | string, message: string): void;
|
||||||
sendChatHistoryMessage(history: ProtocolChatHistory[]): void;
|
sendChatHistoryMessage(history: ProtocolChatHistory[]): void;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { BanManager } from './BanManager.js';
|
|||||||
import { QemuVMShim } from './vm/qemu.js';
|
import { QemuVMShim } from './vm/qemu.js';
|
||||||
import { TheProtocolManager } from './Protocol.js';
|
import { TheProtocolManager } from './Protocol.js';
|
||||||
import { GuacamoleProtocol } from './GuacamoleProtocol.js';
|
import { GuacamoleProtocol } from './GuacamoleProtocol.js';
|
||||||
|
import { BinRectsProtocol } from './BinRectsProtocol.js';
|
||||||
|
|
||||||
let logger = pino();
|
let logger = pino();
|
||||||
|
|
||||||
@@ -99,8 +100,9 @@ async function start() {
|
|||||||
process.on('SIGINT', async () => await stop());
|
process.on('SIGINT', async () => await stop());
|
||||||
process.on('SIGTERM', async () => await stop());
|
process.on('SIGTERM', async () => await stop());
|
||||||
|
|
||||||
// Register protocol(s)
|
// Register protocol(s) that the server supports
|
||||||
TheProtocolManager.registerProtocol("guacamole", () => new GuacamoleProtocol);
|
TheProtocolManager.registerProtocol("guacamole", () => new GuacamoleProtocol);
|
||||||
|
TheProtocolManager.registerProtocol("binary1", () => new BinRectsProtocol);
|
||||||
|
|
||||||
await VM.Start();
|
await VM.Start();
|
||||||
// Start up the server
|
// Start up the server
|
||||||
|
|||||||
Reference in New Issue
Block a user