Eugene hace 1 año
padre
commit
f369998452

+ 0 - 1
.gitignore

@@ -33,7 +33,6 @@ docs/api
 sentry.properties
 sentry-symbols.js
 
-tabby-ssh/util/pagent.exe
 *.psd
 
 crowdin.yml

+ 0 - 3
tabby-ssh/package.json

@@ -15,7 +15,6 @@
   },
   "files": [
     "dist",
-    "util/pagent.exe",
     "typings"
   ],
   "author": "Eugene Pankov",
@@ -23,11 +22,9 @@
   "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"
   },

+ 0 - 1
tabby-ssh/src/api/index.ts

@@ -1,5 +1,4 @@
 export * from './contextMenu'
 export * from './interfaces'
 export * from './importer'
-export * from './proxyStream'
 export { SSHMultiplexerService } from '../services/sshMultiplexer.service'

+ 0 - 61
tabby-ssh/src/api/proxyStream.ts

@@ -1,61 +0,0 @@
-import { Observable, Subject } from 'rxjs'
-import { Duplex } from 'stream'
-
-export class SSHProxyStreamSocket extends Duplex {
-    constructor (private parent: SSHProxyStream) {
-        super({
-            allowHalfOpen: false,
-        })
-    }
-
-    _read (size: number): void {
-        this.parent.requestData(size)
-    }
-
-    _write (chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
-        this.parent.consumeInput(chunk).then(() => callback(null), e => callback(e))
-    }
-
-    _destroy (error: Error|null, callback: (error: Error|null) => void): void {
-        this.parent.handleStopRequest(error).then(() => callback(null), e => callback(e))
-    }
-}
-
-export abstract class SSHProxyStream {
-    get message$ (): Observable<string> { return this.message }
-    get destroyed$ (): Observable<Error|null> { return this.destroyed }
-    get socket (): SSHProxyStreamSocket|null { return this._socket }
-    private message = new Subject<string>()
-    private destroyed = new Subject<Error|null>()
-    private _socket: SSHProxyStreamSocket|null = null
-
-    async start (): Promise<SSHProxyStreamSocket> {
-        if (!this._socket) {
-            this._socket = new SSHProxyStreamSocket(this)
-        }
-        return this._socket
-    }
-
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
-    abstract requestData (size: number): void
-
-    abstract consumeInput (data: Buffer): Promise<void>
-
-    protected emitMessage (message: string): void {
-        this.message.next(message)
-    }
-
-    protected emitOutput (data: Buffer): void {
-        this._socket?.push(data)
-    }
-
-    async handleStopRequest (error: Error|null): Promise<void> {
-        this.destroyed.next(error)
-        this.destroyed.complete()
-        this.message.complete()
-    }
-
-    stop (error?: Error): void {
-        this._socket?.destroy(error)
-    }
-}

+ 1 - 175
tabby-ssh/src/services/ssh.service.ts

@@ -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' })
@@ -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)
-    }
-}

+ 0 - 148
tabby-ssh/yarn.lock

@@ -2,13 +2,6 @@
 # yarn lockfile v1
 
 
-"@luminati-io/socksv5@^0.0.7":
-  version "0.0.7"
-  resolved "https://registry.yarnpkg.com/@luminati-io/socksv5/-/socksv5-0.0.7.tgz#87414177d473c97aaefa907a3fe454d62d2fceca"
-  integrity sha512-paEEbcstjMZb2SvFHsSUOzimkx80/pFmMG5T3XR6Keb4NeBfYWEAtlVeiF39OrHRf9AjpNxahhwzdCAlLXZ4Hw==
-  dependencies:
-    ipv6 "*"
-
 "@types/[email protected]":
   version "20.3.1"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
@@ -24,21 +17,11 @@ ansi-regex@^6.0.1:
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
   integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
 
[email protected]:
-  version "0.2.10"
-  resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
-  integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
-
 balanced-match@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
   integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
-bn.js@^4.0.0, bn.js@^4.1.0:
-  version "4.12.0"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
-  integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
-
 brace-expansion@^1.1.7:
   version "1.1.11"
   resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -47,78 +30,16 @@ brace-expansion@^1.1.7:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
 
-brorand@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
-  integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
-
[email protected]:
-  version "0.4.5"
-  resolved "https://registry.yarnpkg.com/cli/-/cli-0.4.5.tgz#78f9485cd161b566e9a6c72d7170c4270e81db61"
-  integrity sha1-ePlIXNFhtWbppsctcXDEJw6B22E=
-  dependencies:
-    glob ">= 3.1.4"
-
[email protected]:
-  version "0.1.10"
-  resolved "https://registry.yarnpkg.com/cliff/-/cliff-0.1.10.tgz#53be33ea9f59bec85609ee300ac4207603e52013"
-  integrity sha1-U74z6p9ZvshWCe4wCsQgdgPlIBM=
-  dependencies:
-    colors "~1.0.3"
-    eyes "~0.1.8"
-    winston "0.8.x"
-
[email protected]:
-  version "0.6.2"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc"
-  integrity sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=
-
-colors@~1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
-  integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
-
 [email protected]:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
   integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
 
[email protected]:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
-  integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI=
-
-diffie-hellman@^5.0.3:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
-  integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
-  dependencies:
-    bn.js "^4.1.0"
-    miller-rabin "^4.0.0"
-    randombytes "^2.0.0"
-
[email protected], eyes@~0.1.8:
-  version "0.1.8"
-  resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
-  integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
-
 fs.realpath@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
   integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
 
-"glob@>= 3.1.4":
-  version "7.1.6"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
-  integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.4"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
 glob@^7.1.3:
   version "7.2.3"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
@@ -144,35 +65,6 @@ inherits@2:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
 
-ipv6@*:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/ipv6/-/ipv6-3.1.3.tgz#4d9064f9c2dafa0dd10b8b7d76ffca4aad31b3b9"
-  integrity sha1-TZBk+cLa+g3RC4t9dv/KSq0xs7k=
-  dependencies:
-    cli "0.4.x"
-    cliff "0.1.x"
-    sprintf "0.1.x"
-
[email protected]:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-  integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-
-miller-rabin@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
-  integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
-  dependencies:
-    bn.js "^4.0.0"
-    brorand "^1.0.1"
-
-minimatch@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
-  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
-  dependencies:
-    brace-expansion "^1.1.7"
-
 minimatch@^3.1.1:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -192,18 +84,6 @@ path-is-absolute@^1.0.0:
   resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
   integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
 
[email protected]:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
-  integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=
-
-randombytes@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
-  integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
-  dependencies:
-    safe-buffer "^5.1.0"
-
 rimraf@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@@ -216,21 +96,6 @@ run-script-os@^1.1.3:
   resolved "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.6.tgz#8b0177fb1b54c99a670f95c7fdc54f18b9c72347"
   integrity sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==
 
-safe-buffer@^5.1.0:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
-  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-
[email protected]:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/sprintf/-/sprintf-0.1.5.tgz#8f83e39a9317c1a502cb7db8050e51c679f6edcf"
-  integrity sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=
-
[email protected]:
-  version "0.0.10"
-  resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
-  integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
-
 strip-ansi@^7.0.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -252,19 +117,6 @@ tmp@^0.2.0:
   dependencies:
     rimraf "^3.0.0"
 
[email protected]:
-  version "0.8.3"
-  resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0"
-  integrity sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=
-  dependencies:
-    async "0.2.x"
-    colors "0.6.x"
-    cycle "1.0.x"
-    eyes "0.1.x"
-    isstream "0.1.x"
-    pkginfo "0.3.x"
-    stack-trace "0.0.x"
-
 wrappy@1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"