WebSockets work with new telnet server

This commit is contained in:
Bryan Ashby 2020-05-18 19:19:30 -06:00
parent 6d307ec06b
commit e85ba322ce
No known key found for this signature in database
GPG Key ID: B49EB437951D2542
2 changed files with 106 additions and 102 deletions

View File

@ -176,9 +176,6 @@ class TelnetClient {
this.socket.write('\b'); this.socket.write('\b');
return this._logTrace(command, 'Are You There (AYT) - Replied'); return this._logTrace(command, 'Are You There (AYT) - Replied');
}); });
// kick off negotiations
this._banner();
} }
disconnect() { disconnect() {
@ -189,6 +186,21 @@ class TelnetClient {
} }
} }
banner() {
this.socket.do.echo();
this.socket.will.echo(); // we'll echo back
this.socket.will.sga();
this.socket.do.sga();
this.socket.do.transmit_binary();
this.socket.will.transmit_binary();
this.socket.do.ttype();
this.socket.do.naws();
this.socket.do.new_environ();
}
_logTrace(info, msg) { _logTrace(info, msg) {
if (Config().loginServers.telnet.traceConnections) { if (Config().loginServers.telnet.traceConnections) {
const log = this.log || Log; const log = this.log || Log;
@ -209,21 +221,6 @@ class TelnetClient {
this.clientReadyHandled = true; this.clientReadyHandled = true;
this.emit('ready', { firstMenu : Config().loginServers.telnet.firstMenu } ); this.emit('ready', { firstMenu : Config().loginServers.telnet.firstMenu } );
} }
_banner() {
this.socket.do.echo();
this.socket.will.echo(); // we'll echo back
this.socket.will.sga();
this.socket.do.sga();
this.socket.do.transmit_binary();
this.socket.will.transmit_binary();
this.socket.do.ttype();
this.socket.do.naws();
this.socket.do.new_environ();
}
}; };
inherits(TelnetClient, Client); inherits(TelnetClient, Client);
@ -236,6 +233,7 @@ exports.getModule = class TelnetServerModule extends LoginServerModule {
createServer(cb) { createServer(cb) {
this.server = net.createServer( socket => { this.server = net.createServer( socket => {
const client = new TelnetClient(socket); const client = new TelnetClient(socket);
client.banner(); // start negotiations
this.handleNewClient(client, socket, ModuleInfo); this.handleNewClient(client, socket, ModuleInfo);
}); });

View File

@ -24,32 +24,22 @@ const ModuleInfo = exports.moduleInfo = {
packageName : 'codes.l33t.enigma.websocket.server', packageName : 'codes.l33t.enigma.websocket.server',
}; };
function WebSocketClient(ws, req, serverType) { class WebSocketClient extends TelnetClient {
constructor(ws, req, serverType) {
Object.defineProperty(this, 'isSecure', {
get : () => ('secure' === serverType || true === this.proxied) ? true : false,
});
const self = this;
this.dataHandler = function(data) {
if(self.pipedDest) {
self.pipedDest.write(data);
} else {
self.socketBridge.emit('data', data);
}
};
// //
// This bridge makes accessible various calls that client sub classes // This bridge makes accessible various calls that client sub classes
// want to access on I/O socket // want to access on I/O socket
// //
this.socketBridge = new class SocketBridge extends Writable { const socketBridge = new class SocketBridge extends Writable {
constructor(ws) { constructor(ws) {
super(); super();
this.ws = ws; this.ws = ws;
} }
setClient(client) {
this.client = client;
}
end() { end() {
return ws.close(); return ws.close();
} }
@ -62,12 +52,12 @@ function WebSocketClient(ws, req, serverType) {
pipe(dest) { pipe(dest) {
Log.trace('WebSocket SocketBridge pipe()'); Log.trace('WebSocket SocketBridge pipe()');
self.pipedDest = dest; this.client.pipedDest = dest;
} }
unpipe() { unpipe() {
Log.trace('WebSocket SocketBridge unpipe()'); Log.trace('WebSocket SocketBridge unpipe()');
self.pipedDest = null; this.client.pipedDest = null;
} }
resume() { resume() {
@ -76,10 +66,25 @@ function WebSocketClient(ws, req, serverType) {
get remoteAddress() { get remoteAddress() {
// Support X-Forwarded-For and X-Real-IP headers for proxied connections // Support X-Forwarded-For and X-Real-IP headers for proxied connections
return (self.proxied && (req.headers['x-forwarded-for'] || req.headers['x-real-ip'])) || req.connection.remoteAddress; return (this.client.proxied && (req.headers['x-forwarded-for'] || req.headers['x-real-ip'])) || req.connection.remoteAddress;
} }
}(ws); }(ws);
// :TODO: this is quite the clusterfuck...
super(socketBridge);
this.socketBridge = socketBridge;
this.serverType = serverType;
this.socketBridge.setClient(this);
this.dataHandler = function(data) {
if(this.pipedDest) {
this.pipedDest.write(data);
} else {
this.socketBridge.emit('data', data);
}
}.bind(this);
ws.on('message', this.dataHandler); ws.on('message', this.dataHandler);
ws.on('close', () => { ws.on('close', () => {
@ -95,8 +100,6 @@ function WebSocketClient(ws, req, serverType) {
ws.isConnectionAlive = true; ws.isConnectionAlive = true;
}); });
TelnetClient.call(this, this.socketBridge);
Log.trace( { headers : req.headers }, 'WebSocket connection headers' ); Log.trace( { headers : req.headers }, 'WebSocket connection headers' );
// //
@ -116,7 +119,10 @@ function WebSocketClient(ws, req, serverType) {
this.banner(); this.banner();
} }
require('util').inherits(WebSocketClient, TelnetClient); get isSecure() {
return ('secure' === this.serverType || true === this.proxied) ? true : false;
}
}
const WSS_SERVER_TYPES = [ 'insecure', 'secure' ]; const WSS_SERVER_TYPES = [ 'insecure', 'secure' ];