mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-08 13:30:02 +00:00
added warning when server disconnects during auth
This commit is contained in:
parent
cf0da75224
commit
380c306d89
@ -111,7 +111,7 @@ export class SSHSession {
|
|||||||
|
|
||||||
private logger: Logger
|
private logger: Logger
|
||||||
private refCount = 0
|
private refCount = 0
|
||||||
private remainingAuthMethods: AuthMethod[] = []
|
private allAuthMethods: AuthMethod[] = []
|
||||||
private serviceMessage = new Subject<string>()
|
private serviceMessage = new Subject<string>()
|
||||||
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
|
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
|
||||||
private willDestroy = new Subject<void>()
|
private willDestroy = new Subject<void>()
|
||||||
@ -125,6 +125,7 @@ export class SSHSession {
|
|||||||
private translate: TranslateService
|
private translate: TranslateService
|
||||||
private knownHosts: SSHKnownHostsService
|
private knownHosts: SSHKnownHostsService
|
||||||
private privateKeyImporters: AutoPrivateKeyLocator[]
|
private privateKeyImporters: AutoPrivateKeyLocator[]
|
||||||
|
private previouslyDisconnected = false
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
@ -150,7 +151,7 @@ export class SSHSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private addPublicKeyAuthMethod (name: string, contents: Buffer) {
|
private addPublicKeyAuthMethod (name: string, contents: Buffer) {
|
||||||
this.remainingAuthMethods.push({
|
this.allAuthMethods.push({
|
||||||
type: 'publickey',
|
type: 'publickey',
|
||||||
name,
|
name,
|
||||||
contents,
|
contents,
|
||||||
@ -158,7 +159,7 @@ export class SSHSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init (): Promise<void> {
|
async init (): Promise<void> {
|
||||||
this.remainingAuthMethods = [{ type: 'none' }]
|
this.allAuthMethods = [{ type: 'none' }]
|
||||||
if (!this.profile.options.auth || this.profile.options.auth === 'publicKey') {
|
if (!this.profile.options.auth || this.profile.options.auth === 'publicKey') {
|
||||||
if (this.profile.options.privateKeys?.length) {
|
if (this.profile.options.privateKeys?.length) {
|
||||||
for (const pk of this.profile.options.privateKeys) {
|
for (const pk of this.profile.options.privateKeys) {
|
||||||
@ -187,7 +188,7 @@ export class SSHSession {
|
|||||||
if (!spec) {
|
if (!spec) {
|
||||||
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running Agent process is found`)
|
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running Agent process is found`)
|
||||||
} else {
|
} else {
|
||||||
this.remainingAuthMethods.push({
|
this.allAuthMethods.push({
|
||||||
type: 'agent',
|
type: 'agent',
|
||||||
...spec,
|
...spec,
|
||||||
})
|
})
|
||||||
@ -196,21 +197,21 @@ export class SSHSession {
|
|||||||
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
|
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
|
||||||
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
|
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
|
||||||
if (savedPassword) {
|
if (savedPassword) {
|
||||||
this.remainingAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
|
this.allAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
|
||||||
}
|
}
|
||||||
this.remainingAuthMethods.push({ type: 'keyboard-interactive' })
|
this.allAuthMethods.push({ type: 'keyboard-interactive' })
|
||||||
}
|
}
|
||||||
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
|
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
|
||||||
if (this.profile.options.password) {
|
if (this.profile.options.password) {
|
||||||
this.remainingAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
|
this.allAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
|
||||||
}
|
}
|
||||||
const password = await this.passwordStorage.loadPassword(this.profile)
|
const password = await this.passwordStorage.loadPassword(this.profile)
|
||||||
if (password) {
|
if (password) {
|
||||||
this.remainingAuthMethods.push({ type: 'saved-password', password })
|
this.allAuthMethods.push({ type: 'saved-password', password })
|
||||||
}
|
}
|
||||||
this.remainingAuthMethods.push({ type: 'prompt-password' })
|
this.allAuthMethods.push({ type: 'prompt-password' })
|
||||||
}
|
}
|
||||||
this.remainingAuthMethods.push({ type: 'hostbased' })
|
this.allAuthMethods.push({ type: 'hostbased' })
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getAgentConnectionSpec (): Promise<russh.AgentConnectionSpec|null> {
|
private async getAgentConnectionSpec (): Promise<russh.AgentConnectionSpec|null> {
|
||||||
@ -323,9 +324,14 @@ export class SSHSession {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.previouslyDisconnected = false
|
||||||
this.ssh.disconnect$.subscribe(() => {
|
this.ssh.disconnect$.subscribe(() => {
|
||||||
if (this.open) {
|
if (!this.previouslyDisconnected) {
|
||||||
|
this.previouslyDisconnected = true
|
||||||
|
// Let service messages drain
|
||||||
|
setTimeout(() => {
|
||||||
this.destroy()
|
this.destroy()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -508,6 +514,22 @@ export class SSHSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
async handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
||||||
|
const subscription = this.ssh.disconnect$.subscribe(() => {
|
||||||
|
// Auto auth and >=3 keys found
|
||||||
|
if (!this.profile.options.auth && this.allAuthMethods.filter(x => x.type === 'publickey').length >= 3) {
|
||||||
|
this.emitServiceMessage('The server has disconnected during authentication.')
|
||||||
|
this.emitServiceMessage('This may happen if too many private key authentication attemps are made.')
|
||||||
|
this.emitServiceMessage('You can set the specific private key for authentication in the profile settings.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
return await this._handleAuth()
|
||||||
|
} finally {
|
||||||
|
subscription.unsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
|
||||||
this.activePrivateKey = null
|
this.activePrivateKey = null
|
||||||
|
|
||||||
if (!(this.ssh instanceof russh.SSHClient)) {
|
if (!(this.ssh instanceof russh.SSHClient)) {
|
||||||
@ -523,6 +545,7 @@ export class SSHSession {
|
|||||||
return noneResult
|
return noneResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let remainingMethods = [...this.allAuthMethods]
|
||||||
let methodsLeft = noneResult.remainingMethods
|
let methodsLeft = noneResult.remainingMethods
|
||||||
|
|
||||||
function maybeSetRemainingMethods (r: russh.AuthFailure) {
|
function maybeSetRemainingMethods (r: russh.AuthFailure) {
|
||||||
@ -533,13 +556,13 @@ export class SSHSession {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const m = methodsLeft
|
const m = methodsLeft
|
||||||
const method = this.remainingAuthMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
|
const method = remainingMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
|
||||||
|
|
||||||
if (!method) {
|
if (this.previouslyDisconnected || !method) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.remainingAuthMethods = this.remainingAuthMethods.filter(x => x !== method)
|
remainingMethods = remainingMethods.filter(x => x !== method)
|
||||||
|
|
||||||
if (method.type === 'saved-password') {
|
if (method.type === 'saved-password') {
|
||||||
this.emitServiceMessage(this.translate.instant('Using saved password'))
|
this.emitServiceMessage(this.translate.instant('Using saved password'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user