Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Eugeny committed Aug 21, 2024
1 parent 581d7a6 commit f369998
Show file tree
Hide file tree
Showing 6 changed files with 1 addition and 389 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ docs/api
sentry.properties
sentry-symbols.js

tabby-ssh/util/pagent.exe
*.psd

crowdin.yml
Expand Down
3 changes: 0 additions & 3 deletions tabby-ssh/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@
},
"files": [
"dist",
"util/pagent.exe",
"typings"
],
"author": "Eugene Pankov",
"license": "MIT",
"devDependencies": {
"@types/node": "20.3.1",
"ansi-colors": "^4.1.1",
"diffie-hellman": "^5.0.3",
"strip-ansi": "^7.0.0"
},
"dependencies": {
"@luminati-io/socksv5": "^0.0.7",
"run-script-os": "^1.1.3",
"tmp-promise": "^3.0.3"
},
Expand Down
1 change: 0 additions & 1 deletion tabby-ssh/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './contextMenu'
export * from './interfaces'
export * from './importer'
export * from './proxyStream'
export { SSHMultiplexerService } from '../services/sshMultiplexer.service'
61 changes: 0 additions & 61 deletions tabby-ssh/src/api/proxyStream.ts

This file was deleted.

176 changes: 1 addition & 175 deletions tabby-ssh/src/services/ssh.service.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import * as shellQuote from 'shell-quote'
import * as net from 'net'
// import * as fs from 'fs/promises'
import * as tmp from 'tmp-promise'
import socksv5 from '@luminati-io/socksv5'
import { Duplex } from 'stream'
import { Injectable } from '@angular/core'
import { spawn } from 'child_process'
import { ChildProcess } from 'node:child_process'
import { ConfigService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { SSHSession } from '../session/ssh'
import { SSHProfile, SSHProxyStream, SSHProxyStreamSocket } from '../api'
import { SSHProfile } from '../api'
import { PasswordStorageService } from './passwordStorage.service'

@Injectable({ providedIn: 'root' })
Expand Down Expand Up @@ -64,171 +58,3 @@ export class SSHService {
tmpFile?.cleanup()
}
}

export class ProxyCommandStream extends SSHProxyStream {
private process: ChildProcess|null

constructor (private command: string) {
super()
}

async start (): Promise<SSHProxyStreamSocket> {
const argv = shellQuote.parse(this.command)
this.process = spawn(argv[0], argv.slice(1), {
windowsHide: true,
stdio: ['pipe', 'pipe', 'pipe'],
})
this.process.on('error', error => {
this.stop(new Error(`Proxy command has failed to start: ${error.message}`))
})
this.process.on('exit', code => {
this.stop(new Error(`Proxy command has exited with code ${code}`))
})
this.process.stdout?.on('data', data => {
this.emitOutput(data)
})
this.process.stdout?.on('error', (err) => {
this.stop(err)
})
this.process.stderr?.on('data', data => {
this.emitMessage(data.toString())
})
return super.start()
}

requestData (size: number): void {
this.process?.stdout?.read(size)
}

async consumeInput (data: Buffer): Promise<void> {
const process = this.process
if (process) {
await new Promise(resolve => process.stdin?.write(data, resolve))
}
}

async stop (error?: Error): Promise<void> {
this.process?.kill()
super.stop(error)
}
}

export class SocksProxyStream extends SSHProxyStream {
private client: Duplex|null
private header: Buffer|null

constructor (private profile: SSHProfile) {
super()
}

async start (): Promise<SSHProxyStreamSocket> {
this.client = await new Promise((resolve, reject) => {
const connector = socksv5.connect({
host: this.profile.options.host,
port: this.profile.options.port,
proxyHost: this.profile.options.socksProxyHost ?? '127.0.0.1',
proxyPort: this.profile.options.socksProxyPort ?? 5000,
auths: [socksv5.auth.None()],
strictLocalDNS: false,
}, s => {
resolve(s)
this.header = s.read()
if (this.header) {
this.emitOutput(this.header)
}
})
connector.on('error', (err) => {
reject(err)
this.stop(new Error(`SOCKS connection failed: ${err.message}`))
})
})
this.client?.on('data', data => {
if (!this.header || data !== this.header) {
// socksv5 doesn't reliably emit the first data event
this.emitOutput(data)
this.header = null
}
})
this.client?.on('close', error => {
this.stop(error)
})

return super.start()
}

requestData (size: number): void {
this.client?.read(size)
}

async consumeInput (data: Buffer): Promise<void> {
return new Promise((resolve, reject) => {
this.client?.write(data, undefined, err => err ? reject(err) : resolve())
})
}

async stop (error?: Error): Promise<void> {
this.client?.destroy()
super.stop(error)
}
}

export class HTTPProxyStream extends SSHProxyStream {
private client: Duplex|null
private connected = false

constructor (private profile: SSHProfile) {
super()
}

async start (): Promise<SSHProxyStreamSocket> {
this.client = await new Promise((resolve, reject) => {
const connector = net.createConnection({
host: this.profile.options.httpProxyHost!,
port: this.profile.options.httpProxyPort!,
}, () => resolve(connector))
connector.on('error', error => {
reject(error)
this.stop(new Error(`Proxy connection failed: ${error.message}`))
})
})
this.client?.write(Buffer.from(`CONNECT ${this.profile.options.host}:${this.profile.options.port} HTTP/1.1\r\n\r\n`))
this.client?.on('data', (data: Buffer) => {
if (this.connected) {
this.emitOutput(data)
} else {
if (data.slice(0, 5).equals(Buffer.from('HTTP/'))) {
const idx = data.indexOf('\n\n')
const headers = data.slice(0, idx).toString()
const code = parseInt(headers.split(' ')[1])
if (code >= 200 && code < 300) {
this.emitMessage('Connected')
this.emitOutput(data.slice(idx + 2))
this.connected = true
} else {
this.stop(new Error(`Connection failed, code ${code}`))
}
}
}
})
this.client?.on('close', error => {
this.stop(error)
})

return super.start()
}

requestData (size: number): void {
this.client?.read(size)
}

async consumeInput (data: Buffer): Promise<void> {
return new Promise((resolve, reject) => {
this.client?.write(data, undefined, err => err ? reject(err) : resolve())
})
}

async stop (error?: Error): Promise<void> {
this.client?.destroy()
super.stop(error)
}
}
Loading

0 comments on commit f369998

Please sign in to comment.