mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-15 17:09:59 +00:00
ssh: added dynamic port forwarding (fixes #2077)
This commit is contained in:
parent
51d54a8477
commit
0971a85db4
@ -26,9 +26,11 @@
|
|||||||
"ansi-colors": "^4.1.1",
|
"ansi-colors": "^4.1.1",
|
||||||
"cli-spinner": "^0.2.10",
|
"cli-spinner": "^0.2.10",
|
||||||
"run-script-os": "^1.1.3",
|
"run-script-os": "^1.1.3",
|
||||||
"ssh2": "^0.8.2",
|
"socksv5": "^0.0.6",
|
||||||
|
"ssh2": "^0.8.9",
|
||||||
"ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5",
|
"ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5",
|
||||||
"sshpk": "^1.16.1",
|
"sshpk": "^1.16.1",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
"temp": "^0.9.1",
|
"temp": "^0.9.1",
|
||||||
"terminus-terminal": "^1.0.98-nightly.0"
|
"terminus-terminal": "^1.0.98-nightly.0"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import colors from 'ansi-colors'
|
import colors from 'ansi-colors'
|
||||||
|
import stripAnsi from 'strip-ansi'
|
||||||
|
import socksv5 from 'socksv5'
|
||||||
import { BaseSession } from 'terminus-terminal'
|
import { BaseSession } from 'terminus-terminal'
|
||||||
import { Server, Socket, createServer, createConnection } from 'net'
|
import { Server, Socket, createServer, createConnection } from 'net'
|
||||||
import { Client, ClientChannel } from 'ssh2'
|
import { Client, ClientChannel } from 'ssh2'
|
||||||
@ -43,7 +45,7 @@ export interface SSHConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum PortForwardType {
|
export enum PortForwardType {
|
||||||
Local, Remote
|
Local, Remote, Dynamic
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ForwardedPort {
|
export class ForwardedPort {
|
||||||
@ -55,13 +57,40 @@ export class ForwardedPort {
|
|||||||
|
|
||||||
private listener: Server
|
private listener: Server
|
||||||
|
|
||||||
async startLocalListener (callback: (Socket) => void): Promise<void> {
|
async startLocalListener (callback: (accept: () => Socket, reject: () => void, sourceAddress: string|null, sourcePort: number|null, targetAddress: string, targetPort: number) => void): Promise<void> {
|
||||||
this.listener = createServer(callback)
|
if (this.type === PortForwardType.Local) {
|
||||||
return new Promise((resolve, reject) => {
|
this.listener = createServer(s => callback(
|
||||||
this.listener.listen(this.port, '127.0.0.1')
|
() => s,
|
||||||
this.listener.on('error', reject)
|
() => s.destroy(),
|
||||||
this.listener.on('listening', resolve)
|
s.remoteAddress ?? null,
|
||||||
})
|
s.remotePort ?? null,
|
||||||
|
this.targetAddress,
|
||||||
|
this.targetPort,
|
||||||
|
))
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.listener.listen(this.port, this.host)
|
||||||
|
this.listener.on('error', reject)
|
||||||
|
this.listener.on('listening', resolve)
|
||||||
|
})
|
||||||
|
} else if (this.type === PortForwardType.Dynamic) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.listener = socksv5.createServer((info, accept, reject) => {
|
||||||
|
callback(
|
||||||
|
() => accept(true),
|
||||||
|
() => reject(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
info.dstAddr,
|
||||||
|
info.dstPort,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.listener.on('error', reject)
|
||||||
|
this.listener.listen(this.port, this.host, resolve)
|
||||||
|
;(this.listener as any).useAuth(socksv5.auth.None())
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid forward type for a local listener')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stopLocalListener (): void {
|
stopLocalListener (): void {
|
||||||
@ -71,8 +100,10 @@ export class ForwardedPort {
|
|||||||
toString (): string {
|
toString (): string {
|
||||||
if (this.type === PortForwardType.Local) {
|
if (this.type === PortForwardType.Local) {
|
||||||
return `(local) ${this.host}:${this.port} → (remote) ${this.targetAddress}:${this.targetPort}`
|
return `(local) ${this.host}:${this.port} → (remote) ${this.targetAddress}:${this.targetPort}`
|
||||||
} else {
|
} if (this.type === PortForwardType.Remote) {
|
||||||
return `(remote) ${this.host}:${this.port} → (local) ${this.targetAddress}:${this.targetPort}`
|
return `(remote) ${this.host}:${this.port} → (local) ${this.targetAddress}:${this.targetPort}`
|
||||||
|
} else {
|
||||||
|
return `(dynamic) ${this.host}:${this.port}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,25 +263,26 @@ export class SSHSession extends BaseSession {
|
|||||||
|
|
||||||
emitServiceMessage (msg: string): void {
|
emitServiceMessage (msg: string): void {
|
||||||
this.serviceMessage.next(msg)
|
this.serviceMessage.next(msg)
|
||||||
this.logger.info(msg)
|
this.logger.info(stripAnsi(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
async addPortForward (fw: ForwardedPort): Promise<void> {
|
async addPortForward (fw: ForwardedPort): Promise<void> {
|
||||||
if (fw.type === PortForwardType.Local) {
|
if (fw.type === PortForwardType.Local || fw.type === PortForwardType.Dynamic) {
|
||||||
await fw.startLocalListener((socket: Socket) => {
|
await fw.startLocalListener((accept, reject, sourceAddress, sourcePort, targetAddress, targetPort) => {
|
||||||
this.logger.info(`New connection on ${fw}`)
|
this.logger.info(`New connection on ${fw}`)
|
||||||
this.ssh.forwardOut(
|
this.ssh.forwardOut(
|
||||||
socket.remoteAddress || '127.0.0.1',
|
sourceAddress || '127.0.0.1',
|
||||||
socket.remotePort || 0,
|
sourcePort || 0,
|
||||||
fw.targetAddress,
|
targetAddress,
|
||||||
fw.targetPort,
|
targetPort,
|
||||||
(err, stream) => {
|
(err, stream) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote has rejected the forwarded connection via ${fw}: ${err}`)
|
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote has rejected the forwarded connection to ${targetAddress}:${targetPort} via ${fw}: ${err}`)
|
||||||
socket.destroy()
|
reject()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (stream) {
|
if (stream) {
|
||||||
|
const socket = accept()
|
||||||
stream.pipe(socket)
|
stream.pipe(socket)
|
||||||
socket.pipe(stream)
|
socket.pipe(stream)
|
||||||
stream.on('close', () => {
|
stream.on('close', () => {
|
||||||
@ -286,7 +318,7 @@ export class SSHSession extends BaseSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async removePortForward (fw: ForwardedPort): Promise<void> {
|
async removePortForward (fw: ForwardedPort): Promise<void> {
|
||||||
if (fw.type === PortForwardType.Local) {
|
if (fw.type === PortForwardType.Local || fw.type === PortForwardType.Dynamic) {
|
||||||
fw.stopLocalListener()
|
fw.stopLocalListener()
|
||||||
this.forwardedPorts = this.forwardedPorts.filter(x => x !== fw)
|
this.forwardedPorts = this.forwardedPorts.filter(x => x !== fw)
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,22 @@
|
|||||||
.list-group-item.d-flex.align-items-center(*ngFor='let fw of session.forwardedPorts')
|
.list-group-item.d-flex.align-items-center(*ngFor='let fw of session.forwardedPorts')
|
||||||
strong(*ngIf='fw.type === PortForwardType.Local') Local
|
strong(*ngIf='fw.type === PortForwardType.Local') Local
|
||||||
strong(*ngIf='fw.type === PortForwardType.Remote') Remote
|
strong(*ngIf='fw.type === PortForwardType.Remote') Remote
|
||||||
.ml-3 {{fw.host}}:{{fw.port}} → {{fw.targetAddress}}:{{fw.targetPort}}
|
strong(*ngIf='fw.type === PortForwardType.Dynamic') Dynamic
|
||||||
|
.ml-3 {{fw.host}}:{{fw.port}}
|
||||||
|
.ml-2 →
|
||||||
|
.ml-2(*ngIf='fw.type !== PortForwardType.Dynamic') {{fw.targetAddress}}:{{fw.targetPort}}
|
||||||
|
.ml-2(*ngIf='fw.type === PortForwardType.Dynamic') SOCKS proxy
|
||||||
button.btn.btn-link.ml-auto((click)='remove(fw)')
|
button.btn.btn-link.ml-auto((click)='remove(fw)')
|
||||||
i.fas.fa-trash-alt.mr-2
|
i.fas.fa-trash-alt.mr-2
|
||||||
span Remove
|
span Remove
|
||||||
|
|
||||||
.input-group.mb-2
|
.input-group.mb-2(*ngIf='newForward.type === PortForwardType.Dynamic')
|
||||||
|
input.form-control(type='text', [(ngModel)]='newForward.host')
|
||||||
|
.input-group-append
|
||||||
|
.input-group-text :
|
||||||
|
input.form-control(type='number', [(ngModel)]='newForward.port')
|
||||||
|
|
||||||
|
.input-group.mb-2(*ngIf='newForward.type !== PortForwardType.Dynamic')
|
||||||
input.form-control(type='text', [(ngModel)]='newForward.host')
|
input.form-control(type='text', [(ngModel)]='newForward.host')
|
||||||
.input-group-append
|
.input-group-append
|
||||||
.input-group-text :
|
.input-group-text :
|
||||||
@ -42,6 +52,13 @@
|
|||||||
[value]='PortForwardType.Remote'
|
[value]='PortForwardType.Remote'
|
||||||
)
|
)
|
||||||
| Remote
|
| Remote
|
||||||
|
label.btn.btn-secondary.m-0(ngbButtonLabel)
|
||||||
|
input(
|
||||||
|
type='radio',
|
||||||
|
ngbButton,
|
||||||
|
[value]='PortForwardType.Dynamic'
|
||||||
|
)
|
||||||
|
| Dynamic
|
||||||
|
|
||||||
button.btn.btn-primary((click)='addForward()')
|
button.btn.btn-primary((click)='addForward()')
|
||||||
i.fas.fa-check.mr-2
|
i.fas.fa-check.mr-2
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import colors from 'ansi-colors'
|
import colors from 'ansi-colors'
|
||||||
|
import stripAnsi from 'strip-ansi'
|
||||||
import { open as openTemp } from 'temp'
|
import { open as openTemp } from 'temp'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
@ -137,7 +138,7 @@ export class SSHService {
|
|||||||
|
|
||||||
const log = (s: any) => {
|
const log = (s: any) => {
|
||||||
logCallback!(s)
|
logCallback!(s)
|
||||||
this.logger.info(s)
|
this.logger.info(stripAnsi(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
let privateKey: string|null = null
|
let privateKey: string|null = null
|
||||||
|
@ -50,6 +50,7 @@ module.exports = {
|
|||||||
'keytar',
|
'keytar',
|
||||||
'path',
|
'path',
|
||||||
'ngx-toastr',
|
'ngx-toastr',
|
||||||
|
'socksv5',
|
||||||
'windows-native-registry',
|
'windows-native-registry',
|
||||||
'windows-process-tree/build/Release/windows_process_tree.node',
|
'windows-process-tree/build/Release/windows_process_tree.node',
|
||||||
/^rxjs/,
|
/^rxjs/,
|
||||||
|
@ -32,6 +32,11 @@ ansi-colors@^4.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||||
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
||||||
|
|
||||||
|
ansi-regex@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||||
|
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||||
|
|
||||||
asn1@~0.2.0, asn1@~0.2.3:
|
asn1@~0.2.0, asn1@~0.2.3:
|
||||||
version "0.2.4"
|
version "0.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
||||||
@ -44,6 +49,11 @@ assert-plus@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||||
|
|
||||||
|
async@0.2.x:
|
||||||
|
version "0.2.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
|
||||||
|
integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||||
@ -69,11 +79,42 @@ cli-spinner@^0.2.10:
|
|||||||
resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
|
resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
|
||||||
integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
|
integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
|
||||||
|
|
||||||
|
cli@0.4.x:
|
||||||
|
version "0.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/cli/-/cli-0.4.5.tgz#78f9485cd161b566e9a6c72d7170c4270e81db61"
|
||||||
|
integrity sha1-ePlIXNFhtWbppsctcXDEJw6B22E=
|
||||||
|
dependencies:
|
||||||
|
glob ">= 3.1.4"
|
||||||
|
|
||||||
|
cliff@0.1.x:
|
||||||
|
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"
|
||||||
|
|
||||||
|
colors@0.6.x:
|
||||||
|
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=
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
|
cycle@1.0.x:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
|
||||||
|
integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI=
|
||||||
|
|
||||||
dashdash@^1.12.0:
|
dashdash@^1.12.0:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||||
@ -89,6 +130,11 @@ ecc-jsbn@~0.1.1:
|
|||||||
jsbn "~0.1.0"
|
jsbn "~0.1.0"
|
||||||
safer-buffer "^2.1.0"
|
safer-buffer "^2.1.0"
|
||||||
|
|
||||||
|
eyes@0.1.x, 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:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
@ -101,7 +147,7 @@ getpass@^0.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
assert-plus "^1.0.0"
|
assert-plus "^1.0.0"
|
||||||
|
|
||||||
glob@^7.1.3:
|
"glob@>= 3.1.4", glob@^7.1.3:
|
||||||
version "7.1.6"
|
version "7.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||||
@ -126,6 +172,20 @@ inherits@2:
|
|||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
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"
|
||||||
|
|
||||||
|
isstream@0.1.x:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||||
|
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||||
|
|
||||||
jsbn@~0.1.0:
|
jsbn@~0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||||
@ -150,6 +210,11 @@ path-is-absolute@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
|
pkginfo@0.3.x:
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"
|
||||||
|
integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=
|
||||||
|
|
||||||
rimraf@~2.6.2:
|
rimraf@~2.6.2:
|
||||||
version "2.6.3"
|
version "2.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||||
@ -167,6 +232,18 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
|
socksv5@^0.0.6:
|
||||||
|
version "0.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/socksv5/-/socksv5-0.0.6.tgz#1327235ff7e8de21ac434a0a579dc69c3f071061"
|
||||||
|
integrity sha1-EycjX/fo3iGsQ0oKV53GnD8HEGE=
|
||||||
|
dependencies:
|
||||||
|
ipv6 "*"
|
||||||
|
|
||||||
|
sprintf@0.1.x:
|
||||||
|
version "0.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/sprintf/-/sprintf-0.1.5.tgz#8f83e39a9317c1a502cb7db8050e51c679f6edcf"
|
||||||
|
integrity sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=
|
||||||
|
|
||||||
ssh2-streams@Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5:
|
ssh2-streams@Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5:
|
||||||
version "0.4.10"
|
version "0.4.10"
|
||||||
resolved "https://codeload.github.com/Eugeny/ssh2-streams/tar.gz/75f6d3425d071ac73a18fd46e2f5e738bfe897c5"
|
resolved "https://codeload.github.com/Eugeny/ssh2-streams/tar.gz/75f6d3425d071ac73a18fd46e2f5e738bfe897c5"
|
||||||
@ -184,7 +261,7 @@ ssh2-streams@~0.4.10:
|
|||||||
bcrypt-pbkdf "^1.0.2"
|
bcrypt-pbkdf "^1.0.2"
|
||||||
streamsearch "~0.1.2"
|
streamsearch "~0.1.2"
|
||||||
|
|
||||||
ssh2@^0.8.2:
|
ssh2@^0.8.9:
|
||||||
version "0.8.9"
|
version "0.8.9"
|
||||||
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3"
|
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3"
|
||||||
integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==
|
integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==
|
||||||
@ -206,11 +283,23 @@ sshpk@^1.16.1:
|
|||||||
safer-buffer "^2.0.2"
|
safer-buffer "^2.0.2"
|
||||||
tweetnacl "~0.14.0"
|
tweetnacl "~0.14.0"
|
||||||
|
|
||||||
|
stack-trace@0.0.x:
|
||||||
|
version "0.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||||
|
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
|
||||||
|
|
||||||
streamsearch@~0.1.2:
|
streamsearch@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
|
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
|
||||||
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
|
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||||
|
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.0"
|
||||||
|
|
||||||
temp@^0.9.1:
|
temp@^0.9.1:
|
||||||
version "0.9.1"
|
version "0.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697"
|
resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.1.tgz#2d666114fafa26966cd4065996d7ceedd4dd4697"
|
||||||
@ -228,6 +317,19 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||||
|
|
||||||
|
winston@0.8.x:
|
||||||
|
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:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user