1
1
mirror of https://github.com/Eugeny/tabby.git synced 2024-12-23 18:44:20 +03:00

telnet command sequence fixes

This commit is contained in:
Eugene Pankov 2021-09-17 00:23:04 +02:00
parent a99fcbb71d
commit 60a1a1f21c
No known key found for this signature in database
GPG Key ID: 5896FCBBDD1CF4F4

View File

@ -17,6 +17,7 @@ export interface TelnetProfileOptions extends StreamProcessingOptions, LoginScri
}
enum TelnetCommands {
SUBOPTION_SEND = 1,
SUBOPTION_END = 240,
GA = 249,
SUBOPTION = 250,
@ -35,7 +36,9 @@ enum TelnetOptions {
NEGO_WINDOW_SIZE = 0x1f,
NEGO_TERMINAL_SPEED = 0x20,
STATUS = 0x05,
REMOTE_FLOW_CONTROL = 0x21,
X_DISPLAY_LOCATION = 0x23,
NEW_ENVIRON = 0x27,
}
export class TelnetSession extends BaseSession {
@ -48,6 +51,7 @@ export class TelnetSession extends BaseSession {
private echoEnabled = false
private lastWidth = 0
private lastHeight = 0
private requestedOptions = new Set<number>()
constructor (
injector: Injector,
@ -107,6 +111,11 @@ export class TelnetSession extends BaseSession {
})
}
requestOption (cmd: TelnetCommands, option: TelnetOptions): void {
this.requestedOptions.add(option)
this.emitTelnet(cmd, option)
}
emitServiceMessage (msg: string): void {
this.serviceMessage.next(msg)
this.logger.info(stripAnsi(msg))
@ -115,7 +124,7 @@ export class TelnetSession extends BaseSession {
onData (data: Buffer): void {
if (!this.telnetProtocol && data[0] === TelnetCommands.IAC) {
this.telnetProtocol = true
this.emitTelnet(TelnetCommands.DO, TelnetOptions.SUPPRESS_GO_AHEAD)
this.requestOption(TelnetCommands.DO, TelnetOptions.SUPPRESS_GO_AHEAD)
this.emitTelnet(TelnetCommands.WILL, TelnetOptions.TERMINAL_TYPE)
this.emitTelnet(TelnetCommands.WILL, TelnetOptions.NEGO_WINDOW_SIZE)
}
@ -126,7 +135,7 @@ export class TelnetSession extends BaseSession {
}
emitTelnet (command: TelnetCommands, option: TelnetOptions): void {
this.logger.debug('>', TelnetCommands[command], TelnetOptions[option])
this.logger.debug('>', TelnetCommands[command], TelnetOptions[option] || option)
this.socket.write(Buffer.from([TelnetCommands.IAC, command, option]))
}
@ -157,6 +166,14 @@ export class TelnetSession extends BaseSession {
data = data.slice(3)
this.logger.debug('<', commandName || command, optionName || option)
if (command === TelnetCommands.WILL || command === TelnetCommands.WONT) {
if (this.requestedOptions.has(option)) {
this.requestedOptions.delete(option)
continue
}
}
if (command === TelnetCommands.WILL) {
if ([
TelnetOptions.SUPPRESS_GO_AHEAD,
@ -170,14 +187,13 @@ export class TelnetSession extends BaseSession {
}
if (command === TelnetCommands.DO) {
if (option === TelnetOptions.NEGO_WINDOW_SIZE) {
this.emitSize()
this.emitTelnet(TelnetCommands.WILL, option)
this.emitSize()
} else if (option === TelnetOptions.ECHO) {
this.echoEnabled = true
this.emitTelnet(TelnetCommands.WILL, option)
} else if (option === TelnetOptions.TERMINAL_TYPE) {
this.emitTelnet(TelnetCommands.WILL, option)
this.emitTelnetSuboption(option, Buffer.from([0, ...Buffer.from('XTERM-256COLOR')]))
} else {
this.logger.debug('(!) Unhandled option')
this.emitTelnet(TelnetCommands.WONT, option)
@ -196,6 +212,11 @@ export class TelnetSession extends BaseSession {
const endIndex = data.indexOf(TelnetCommands.IAC)
const optionValue = data.slice(0, endIndex)
this.logger.debug('<', commandName || command, optionName || option, optionValue)
if (option === TelnetOptions.TERMINAL_TYPE && optionValue[0] === TelnetCommands.SUBOPTION_SEND) {
this.emitTelnetSuboption(option, Buffer.from([0, ...Buffer.from('XTERM-256COLOR')]))
}
data = data.slice(endIndex + 2)
}
} else {