updated ssh2

This commit is contained in:
Eugene Pankov 2021-06-04 22:54:12 +02:00
parent d435abd944
commit 779eb235f3
No known key found for this signature in database
GPG Key ID: 5896FCBBDD1CF4F4
15 changed files with 138 additions and 179 deletions

View File

@ -38,6 +38,7 @@
"npm": "6",
"path": "0.12.7",
"rxjs": "^7.1.0",
"ssh2": "^1.1.0",
"yargs": "^17.0.1",
"zone.js": "^0.11.4"
},

View File

@ -73,10 +73,7 @@ const builtinModules = [
const cachedBuiltinModules = {}
builtinModules.forEach(m => {
const label = 'Caching ' + m
console.time(label)
cachedBuiltinModules[m] = nodeRequire(m)
console.timeEnd(label)
})
const originalRequire = (global as any).require
@ -183,14 +180,11 @@ export async function loadPlugins (foundPlugins: PluginInfo[], progress: Progres
console.info(`Loading ${foundPlugin.name}: ${nodeRequire.resolve(foundPlugin.path)}`)
progress(index, foundPlugins.length)
try {
const label = 'Loading ' + foundPlugin.name
console.time(label)
const packageModule = nodeRequire(foundPlugin.path)
const pluginModule = packageModule.default.forRoot ? packageModule.default.forRoot() : packageModule.default
pluginModule.pluginName = foundPlugin.name
pluginModule.bootstrap = packageModule.bootstrap
plugins.push(pluginModule)
console.timeEnd(label)
await new Promise(x => setTimeout(x, 50))
} catch (error) {
console.error(`Could not load ${foundPlugin.name}:`, error)

View File

@ -295,7 +295,7 @@ asap@^2.0.0:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
asn1@~0.2.3:
asn1@^0.2.4, asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
@ -332,7 +332,7 @@ base64-js@^1.3.1:
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
bcrypt-pbkdf@^1.0.0:
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
@ -686,6 +686,13 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
cpu-features@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.2.tgz#9f636156f1155fd04bdbaa028bb3c2fbef3cea7a"
integrity sha512-/2yieBqvMcRj8McNzkycjW2v3OIUOibBfd2dLEJ0nWts8NobAxwiyw9phVNS6oDL8x8tz9F7uNVFEVpJncQpeA==
dependencies:
nan "^2.14.1"
create-error-class@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
@ -2081,7 +2088,7 @@ mz@^2.7.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@^2.13.2, nan@^2.14.0, nan@^2.14.2:
nan@^2.13.2, nan@^2.14.0, nan@^2.14.1, nan@^2.14.2:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
@ -3205,6 +3212,17 @@ split-on-first@^1.0.0:
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
ssh2@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.1.0.tgz#43dd24930e15e317687f519d6b40270d9cd00d00"
integrity sha512-CidQLG2ZacoT0Z7O6dOyisj4JdrOrLVJ4KbHjVNz9yI1vO08FAYQPcnkXY9BP8zeYo+J/nBgY6Gg4R7w4WFWtg==
dependencies:
asn1 "^0.2.4"
bcrypt-pbkdf "^1.0.2"
optionalDependencies:
cpu-features "0.0.2"
nan "^2.14.2"
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz"

View File

@ -46,7 +46,6 @@
"shelljs": "0.8.4",
"source-code-pro": "^2.38.0",
"source-sans-pro": "3.6.0",
"ssh2-streams": "^0.4.10",
"style-loader": "^2.0.0",
"svg-inline-loader": "^0.8.2",
"tslib": "^2.2.0",

View File

@ -18,7 +18,6 @@
"license": "MIT",
"devDependencies": {
"@types/node": "14.14.14",
"@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1",
"binstring": "^0.2.1",
"buffer-replace": "^1.0.0",

View File

@ -2,31 +2,11 @@
# yarn lockfile v1
"@types/node@*":
version "14.14.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d"
integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==
"@types/node@14.14.14":
version "14.14.14"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae"
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==
"@types/ssh2-streams@*":
version "0.1.7"
resolved "https://registry.yarnpkg.com/@types/ssh2-streams/-/ssh2-streams-0.1.7.tgz#bf79349ec85a4dfb5b3fd9f4a05af729121f07e6"
integrity sha512-cQNV72C+BOG7G8WNGarTQdB2Ii37cJlWatSpx5zTYxtI2ZvUt2lbq6Nc2XZ4kbge28V7Xe5KYYr82d96/rDMnQ==
dependencies:
"@types/node" "*"
"@types/ssh2@^0.5.35":
version "0.5.45"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.45.tgz#14e293ec2a4d4c8a5434a7989a676b87340aa870"
integrity sha512-SAQITTyO/jOoskSAw2T/9sveX4lhTzx7zdeYR0t04RMhZQrEIzvrAoCStSxYwvwZ5ofek1JWeW9x2yOK3GOUlg==
dependencies:
"@types/node" "*"
"@types/ssh2-streams" "*"
ansi-color@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-color/-/ansi-color-0.2.1.tgz#3e75c037475217544ed763a8db5709fa9ae5bf9a"

View File

@ -22,12 +22,9 @@
"license": "MIT",
"devDependencies": {
"@types/node": "14.14.31",
"@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1",
"cli-spinner": "^0.2.10",
"clone-deep": "^4.0.1",
"ssh2": "^0.8.9",
"ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5",
"sshpk": "Eugeny/node-sshpk#89ed17dfae425a8b629873c8337e77d26838c04f",
"strip-ansi": "^7.0.0"
},

View File

@ -1,12 +1,16 @@
import colors from 'ansi-colors'
import stripAnsi from 'strip-ansi'
import socksv5 from 'socksv5'
import { Injector } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseSession } from 'terminus-terminal'
import { Server, Socket, createServer, createConnection } from 'net'
import { Client, ClientChannel } from 'ssh2'
import { Logger } from 'terminus-core'
import { Subject, Observable } from 'rxjs'
import { ProxyCommandStream } from './services/ssh.service'
import { PasswordStorageService } from './services/passwordStorage.service'
import { PromptModalComponent } from './components/promptModal.component'
export interface LoginScript {
expect: string
@ -129,12 +133,22 @@ export class SSHSession extends BaseSession {
logger: Logger
jumpStream: any
proxyCommandStream: ProxyCommandStream|null = null
authMethodsLeft: string[] = []
savedPassword: string|undefined
get serviceMessage$ (): Observable<string> { return this.serviceMessage }
private serviceMessage = new Subject<string>()
private keychainPasswordUsed = false
private passwordStorage: PasswordStorageService
private ngbModal: NgbModal
constructor (public connection: SSHConnection) {
constructor (
injector: Injector,
public connection: SSHConnection
) {
super()
this.passwordStorage = injector.get(PasswordStorageService)
this.ngbModal = injector.get(NgbModal)
this.scripts = connection.scripts ?? []
this.destroyed$.subscribe(() => {
for (const port of this.forwardedPorts) {
@ -197,7 +211,7 @@ export class SSHSession extends BaseSession {
if (match) {
this.logger.info('Executing script: "' + cmd + '"')
this.shell!.write(cmd + '\n')
this.shell.write(cmd + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
if (script.optional) {
@ -296,6 +310,67 @@ export class SSHSession extends BaseSession {
this.logger.info(stripAnsi(msg))
}
async handleAuth (methodsLeft?: string[]): Promise<any> {
while (true) {
const method = this.authMethodsLeft.shift()
if (!method) {
return false
}
if (methodsLeft && !methodsLeft.includes(method) && method !== 'agent') {
// Agent can still be used even if not in methodsLeft
this.logger.info('Server does not support auth method', method)
continue
}
if (method === 'password') {
if (this.connection.password) {
this.emitServiceMessage('Using preset password')
return {
type: 'password',
username: this.connection.user,
password: this.connection.password,
}
}
if (!this.keychainPasswordUsed) {
const password = await this.passwordStorage.loadPassword(this.connection)
if (password) {
this.emitServiceMessage('Trying saved password')
this.keychainPasswordUsed = true
return {
type: 'password',
username: this.connection.user,
password,
}
}
}
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = `Password for ${this.connection.user}@${this.connection.host}`
modal.componentInstance.password = true
modal.componentInstance.showRememberCheckbox = true
try {
const result = await modal.result
if (result) {
if (result.remember) {
this.savedPassword = result.value
}
return {
type: 'password',
username: this.connection.user,
password: result.value,
}
} else {
continue
}
} catch {
continue
}
}
return method
}
}
async addPortForward (fw: ForwardedPort): Promise<void> {
if (fw.type === PortForwardType.Local || fw.type === PortForwardType.Dynamic) {
await fw.startLocalListener((accept, reject, sourceAddress, sourcePort, targetAddress, targetPort) => {
@ -417,7 +492,7 @@ export class SSHSession extends BaseSession {
for (const script of this.scripts) {
if (!script.expect) {
console.log('Executing script:', script.send)
this.shell!.write(script.send + '\n')
this.shell.write(script.send + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
break

View File

@ -197,28 +197,28 @@
.form-line.align-items-start
.header
.title Ciphers
.w-50
.w-75
div(*ngFor='let alg of supportedAlgorithms.cipher')
checkbox([text]='alg', [(ngModel)]='algorithms.cipher[alg]')
.form-line.align-items-start
.header
.title Key exchange
.w-50
.w-75
div(*ngFor='let alg of supportedAlgorithms.kex')
checkbox([text]='alg', [(ngModel)]='algorithms.kex[alg]')
.form-line.align-items-start
.header
.title HMAC
.w-50
.w-75
div(*ngFor='let alg of supportedAlgorithms.hmac')
checkbox([text]='alg', [(ngModel)]='algorithms.hmac[alg]')
.form-line.align-items-start
.header
.title Host key
.w-50
.w-75
div(*ngFor='let alg of supportedAlgorithms.serverHostKey')
checkbox([text]='alg', [(ngModel)]='algorithms.serverHostKey[alg]')

View File

@ -8,7 +8,7 @@ import { ElectronService, HostAppService, ConfigService, PlatformService } from
import { PasswordStorageService } from '../services/passwordStorage.service'
import { SSHConnection, LoginScript, ForwardedPortConfig, SSHAlgorithmType, ALGORITHM_BLACKLIST } from '../api'
import { PromptModalComponent } from './promptModal.component'
import { ALGORITHMS } from 'ssh2-streams/lib/constants'
import * as ALGORITHMS from 'ssh2/lib/protocol/constants'
/** @hidden */
@Component({
@ -39,15 +39,15 @@ export class EditConnectionModalComponent {
[SSHAlgorithmType.KEX]: 'SUPPORTED_KEX',
[SSHAlgorithmType.HOSTKEY]: 'SUPPORTED_SERVER_HOST_KEY',
[SSHAlgorithmType.CIPHER]: 'SUPPORTED_CIPHER',
[SSHAlgorithmType.HMAC]: 'SUPPORTED_HMAC',
[SSHAlgorithmType.HMAC]: 'SUPPORTED_MAC',
}[k]
const defaultAlg = {
[SSHAlgorithmType.KEX]: 'KEX',
[SSHAlgorithmType.HOSTKEY]: 'SERVER_HOST_KEY',
[SSHAlgorithmType.CIPHER]: 'CIPHER',
[SSHAlgorithmType.HMAC]: 'HMAC',
[SSHAlgorithmType.KEX]: 'DEFAULT_KEX',
[SSHAlgorithmType.HOSTKEY]: 'DEFAULT_SERVER_HOST_KEY',
[SSHAlgorithmType.CIPHER]: 'DEFAULT_CIPHER',
[SSHAlgorithmType.HMAC]: 'DEFAULT_MAC',
}[k]
this.supportedAlgorithms[k] = ALGORITHMS[supportedAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x))
this.supportedAlgorithms[k] = ALGORITHMS[supportedAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x)).sort()
this.defaultAlgorithms[k] = ALGORITHMS[defaultAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x))
}

View File

@ -154,7 +154,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
this.reconnectOffered = true
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
if (!this.session?.open && this.reconnectOffered) {
this.reconnect()
}
})

View File

@ -1,10 +1,9 @@
import colors from 'ansi-colors'
import { Duplex } from 'stream'
import * as crypto from 'crypto'
import { Injectable, NgZone } from '@angular/core'
import { Injectable, Injector, NgZone } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { Client } from 'ssh2'
import { SSH2Stream } from 'ssh2-streams'
import * as fs from 'mz/fs'
import { exec } from 'child_process'
import * as path from 'path'
@ -25,6 +24,7 @@ export class SSHService {
private logger: Logger
private constructor (
private injector: Injector,
private log: LogService,
private zone: NgZone,
private ngbModal: NgbModal,
@ -39,7 +39,7 @@ export class SSHService {
}
createSession (connection: SSHConnection): SSHSession {
const session = new SSHSession(connection)
const session = new SSHSession(this.injector, connection)
session.logger = this.log.create(`ssh-${connection.host}-${connection.port}`)
return session
}
@ -114,7 +114,6 @@ export class SSHService {
const ssh = new Client()
session.ssh = ssh
let connected = false
let savedPassword: string|null = null
const algorithms = {}
for (const key of Object.keys(session.connection.algorithms ?? {})) {
algorithms[key] = session.connection.algorithms![key].filter(x => !ALGORITHM_BLACKLIST.includes(x))
@ -123,8 +122,8 @@ export class SSHService {
const resultPromise: Promise<void> = new Promise(async (resolve, reject) => {
ssh.on('ready', () => {
connected = true
if (savedPassword) {
this.passwordStorage.savePassword(session.connection, savedPassword)
if (session.savedPassword) {
this.passwordStorage.savePassword(session.connection, session.savedPassword)
}
for (const fw of session.connection.forwardedPorts ?? []) {
@ -133,6 +132,9 @@ export class SSHService {
this.zone.run(resolve)
})
ssh.on('handshake', negotiated => {
this.logger.info('Handshake complete:', negotiated)
})
ssh.on('error', error => {
if (error.message === 'All configured authentication methods failed') {
this.passwordStorage.deletePassword(session.connection)
@ -197,7 +199,7 @@ export class SSHService {
agent = process.env.SSH_AUTH_SOCK!
}
const authMethodsLeft = ['none']
session.authMethodsLeft = ['none']
if (!session.connection.auth || session.connection.auth === 'publicKey') {
try {
privateKey = await this.loadPrivateKeyForSession(session)
@ -207,23 +209,23 @@ export class SSHService {
if (!privateKey) {
session.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Private key auth selected, but no key is loaded`)
} else {
authMethodsLeft.push('publickey')
session.authMethodsLeft.push('publickey')
}
}
if (!session.connection.auth || session.connection.auth === 'agent') {
if (!agent) {
session.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running agent is detected`)
} else {
authMethodsLeft.push('agent')
session.authMethodsLeft.push('agent')
}
}
if (!session.connection.auth || session.connection.auth === 'password') {
authMethodsLeft.push('password')
session.authMethodsLeft.push('password')
}
if (!session.connection.auth || session.connection.auth === 'keyboardInteractive') {
authMethodsLeft.push('keyboard-interactive')
session.authMethodsLeft.push('keyboard-interactive')
}
authMethodsLeft.push('hostbased')
session.authMethodsLeft.push('hostbased')
try {
if (session.connection.proxyCommand) {
@ -257,19 +259,10 @@ export class SSHService {
},
hostHash: 'sha256' as any,
algorithms,
authHandler: methodsLeft => {
while (true) {
const method = authMethodsLeft.shift()
if (!method) {
return false
}
if (methodsLeft && !methodsLeft.includes(method) && method !== 'agent') {
// Agent can still be used even if not in methodsLeft
this.logger.info('Server does not support auth method', method)
continue
}
return method
}
authHandler: (methodsLeft, partialSuccess, callback) => {
this.zone.run(async () => {
callback(await session.handleAuth(methodsLeft))
})
},
} as any)
} catch (e) {
@ -277,41 +270,6 @@ export class SSHService {
throw e
}
let keychainPasswordUsed = false
;(ssh as any).config.password = () => this.zone.run(async () => {
if (session.connection.password) {
log('Using preset password')
return session.connection.password
}
if (!keychainPasswordUsed) {
const password = await this.passwordStorage.loadPassword(session.connection)
if (password) {
log('Trying saved password')
keychainPasswordUsed = true
return password
}
}
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = `Password for ${session.connection.user}@${session.connection.host}`
modal.componentInstance.password = true
modal.componentInstance.showRememberCheckbox = true
try {
const result = await modal.result
if (result) {
if (result.remember) {
savedPassword = result.value
}
return result.value
}
return ''
} catch {
return ''
}
})
return resultPromise
}
@ -479,9 +437,3 @@ export class ProxyCommandStream extends Duplex {
callback(error)
}
}
/* eslint-disable */
const _authPassword = SSH2Stream.prototype.authPassword
SSH2Stream.prototype.authPassword = async function (username, passwordFn: any) {
_authPassword.bind(this)(username, await passwordFn())
} as any

View File

@ -2,26 +2,11 @@
# yarn lockfile v1
"@types/node@*", "@types/node@14.14.31":
"@types/node@14.14.31":
version "14.14.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
"@types/ssh2-streams@*":
version "0.1.7"
resolved "https://registry.yarnpkg.com/@types/ssh2-streams/-/ssh2-streams-0.1.7.tgz#bf79349ec85a4dfb5b3fd9f4a05af729121f07e6"
integrity sha512-cQNV72C+BOG7G8WNGarTQdB2Ii37cJlWatSpx5zTYxtI2ZvUt2lbq6Nc2XZ4kbge28V7Xe5KYYr82d96/rDMnQ==
dependencies:
"@types/node" "*"
"@types/ssh2@^0.5.35":
version "0.5.46"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.46.tgz#e12341a242aea0e98ac2dec89e039bf421fd3584"
integrity sha512-1pC8FHrMPYdkLoUOwTYYifnSEPzAFZRsp3JFC/vokQ+dRrVI+hDBwz0SNmQ3pL6h39OSZlPs0uCG7wKJkftnaA==
dependencies:
"@types/node" "*"
"@types/ssh2-streams" "*"
ansi-colors@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
@ -32,7 +17,7 @@ ansi-regex@^6.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.0.tgz#ecc7f5933cbe5ac7b33e209a5ff409ab1669c6b2"
integrity sha512-tAaOSrWCHF+1Ear1Z4wnJCXA9GGox4K6Ic85a5qalES2aeEwQGr7UC93mwef49536PkCYjzkp0zIxfFvexJ6zQ==
asn1@~0.2.0, asn1@~0.2.3:
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
@ -54,7 +39,7 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
@ -265,30 +250,6 @@ sprintf@0.1.x:
resolved "https://registry.yarnpkg.com/sprintf/-/sprintf-0.1.5.tgz#8f83e39a9317c1a502cb7db8050e51c679f6edcf"
integrity sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=
ssh2-streams@Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5:
version "0.4.10"
resolved "https://codeload.github.com/Eugeny/ssh2-streams/tar.gz/75f6d3425d071ac73a18fd46e2f5e738bfe897c5"
dependencies:
asn1 "~0.2.0"
bcrypt-pbkdf "^1.0.2"
streamsearch "~0.1.2"
ssh2-streams@~0.4.10:
version "0.4.10"
resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34"
integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==
dependencies:
asn1 "~0.2.0"
bcrypt-pbkdf "^1.0.2"
streamsearch "~0.1.2"
ssh2@^0.8.9:
version "0.8.9"
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.8.9.tgz#54da3a6c4ba3daf0d8477a538a481326091815f3"
integrity sha512-GmoNPxWDMkVpMFa9LVVzQZHF6EW3WKmBwL+4/GeILf2hFmix5Isxm7Amamo8o7bHiU0tC+wXsGcUXOxp8ChPaw==
dependencies:
ssh2-streams "~0.4.10"
sshpk@Eugeny/node-sshpk#89ed17dfae425a8b629873c8337e77d26838c04f:
version "1.16.1"
resolved "https://codeload.github.com/Eugeny/node-sshpk/tar.gz/89ed17dfae425a8b629873c8337e77d26838c04f"
@ -308,11 +269,6 @@ stack-trace@0.0.x:
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
streamsearch@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
strip-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.0.tgz#1dc49b980c3a4100366617adac59327eefdefcb0"

View File

@ -99,6 +99,8 @@ module.exports = options => {
'path',
'readline',
'serialport',
'ssh2',
'ssh2/lib/protocol/constants',
'socksv5',
'stream',
'windows-native-registry',

View File

@ -987,7 +987,7 @@ asar@^3.0.0, asar@^3.0.3:
optionalDependencies:
"@types/glob" "^7.1.1"
asn1@~0.2.0, asn1@~0.2.3:
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
@ -1141,7 +1141,7 @@ base@^0.11.1:
mixin-deep "^1.2.0"
pascalcase "^0.1.1"
bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
@ -7586,15 +7586,6 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
ssh2-streams@^0.4.10:
version "0.4.10"
resolved "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz"
integrity sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==
dependencies:
asn1 "~0.2.0"
bcrypt-pbkdf "^1.0.2"
streamsearch "~0.1.2"
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz"
@ -7658,11 +7649,6 @@ stream-shift@^1.0.0:
resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz"
integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=
streamsearch@~0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"