Skip to content

Commit a0b7f88

Browse files
committed
fix: better error handling
1 parent 6d28a43 commit a0b7f88

File tree

2 files changed

+66
-37
lines changed

2 files changed

+66
-37
lines changed

client/src/connection/ssh/auth.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,12 @@ export class AuthHandler {
118118
* @param resolve a function that resolves the promise that is waiting for the password
119119
* @param username the user name to use for the connection
120120
*/
121-
passwordAuth = (cb: NextAuthHandler, username: string) => {
122-
this._authPresenter.presentPasswordPrompt(username).then((pw) => {
123-
cb({
124-
type: "password",
125-
password: pw,
126-
username: username,
127-
});
121+
passwordAuth = async (cb: NextAuthHandler, username: string) => {
122+
const pw = await this._authPresenter.presentPasswordPrompt(username);
123+
cb({
124+
type: "password",
125+
password: pw,
126+
username: username,
128127
});
129128
};
130129

@@ -134,7 +133,7 @@ export class AuthHandler {
134133
* @param resolve a function that resolves the promise that is waiting for authentication
135134
* @param username the user name to use for the connection
136135
*/
137-
keyboardInteractiveAuth = (cb: NextAuthHandler, username: string) => {
136+
keyboardInteractiveAuth = async (cb: NextAuthHandler, username: string) => {
138137
cb({
139138
type: "keyboard-interactive",
140139
username: username,
@@ -172,7 +171,7 @@ export class AuthHandler {
172171
* @param privateKeyFilePath the path to the private key file defined in the connection profile
173172
* @param username the user name to use for the connection
174173
*/
175-
privateKeyAuth = (
174+
privateKeyAuth = async (
176175
cb: NextAuthHandler,
177176
privateKeyFilePath: string,
178177
username: string,
@@ -186,22 +185,23 @@ export class AuthHandler {
186185
"Encrypted private OpenSSH key detected, but no passphrase given";
187186
// key is encrypted, prompt for passphrase
188187
if (passphraseRequired) {
189-
this._authPresenter.presentPassphrasePrompt().then((passphrase) => {
190-
//parse the keyfile using the passphrase
191-
const passphrasedKeyContentsResult = this._keyParser.parseKey(
192-
privateKeyFilePath,
193-
passphrase,
194-
);
195-
196-
if (passphrasedKeyContentsResult instanceof Error) {
197-
throw passphrasedKeyContentsResult;
198-
}
199-
cb({
200-
type: "publickey",
201-
key: passphrasedKeyContentsResult,
202-
passphrase: passphrase,
203-
username: username,
204-
});
188+
const passphrase = await this._authPresenter.presentPassphrasePrompt();
189+
190+
//parse the keyfile using the passphrase
191+
const passphrasedKeyContentsResult = this._keyParser.parseKey(
192+
privateKeyFilePath,
193+
passphrase,
194+
);
195+
196+
if (passphrasedKeyContentsResult instanceof Error) {
197+
throw passphrasedKeyContentsResult;
198+
}
199+
200+
cb({
201+
type: "publickey",
202+
key: passphrasedKeyContentsResult,
203+
passphrase: passphrase,
204+
username: username,
205205
});
206206
} else {
207207
if (hasParseError) {

client/src/connection/ssh/index.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export class SSHSession extends Session {
5353
private _authHandler: AuthHandler;
5454
private _workDirectory: string;
5555
private _workDirectoryParser: LineParser;
56+
private _authsLeft: AuthenticationType[];
5657

5758
constructor(c?: Config, client?: Client) {
5859
super();
@@ -65,6 +66,7 @@ export class SSHSession extends Session {
6566
WORK_DIR_END_TAG,
6667
false,
6768
);
69+
this._authsLeft = [];
6870
}
6971

7072
public sessionId? = (): string => {
@@ -124,20 +126,30 @@ export class SSHSession extends Session {
124126

125127
public close = (): void | Promise<void> => {
126128
if (!this._stream) {
129+
this.disposeResources();
127130
return;
128131
}
129132
this._stream.write("endsas;\n");
130133
this._stream.close();
131134
};
132135

133136
private onConnectionClose = () => {
137+
if (!this._sessionReady) {
138+
this._reject?.(new Error(l10n.t("Could not connect to the SAS server.")));
139+
}
140+
141+
this.disposeResources();
142+
};
143+
144+
private disposeResources = () => {
134145
this._stream = undefined;
135146
this._resolve = undefined;
136147
this._reject = undefined;
137148
this._html5FileName = "";
138149
this._workDirectory = undefined;
139150
this.clearAuthState();
140151
sessionInstance = undefined;
152+
this._authsLeft = [];
141153
};
142154

143155
private onConnectionError = (err: Error) => {
@@ -297,7 +309,7 @@ export class SSHSession extends Session {
297309

298310
private handleSSHAuthentication: AuthHandlerMiddleware = (
299311
authsLeft: AuthenticationType[],
300-
_partialSuccess: boolean,
312+
partialSuccess: boolean,
301313
nextAuth: NextAuthHandler,
302314
) => {
303315
if (!authsLeft) {
@@ -313,30 +325,47 @@ export class SSHSession extends Session {
313325
return false; //returning false will stop the authentication process
314326
}
315327

316-
const authMethod = authsLeft.shift();
328+
if (this._authsLeft.length === 0 || partialSuccess) {
329+
this._authsLeft = authsLeft;
330+
}
331+
332+
const authMethod = this._authsLeft.shift();
333+
317334
switch (authMethod) {
318335
case "publickey": {
319336
//user set a keyfile path in profile config
320337
if (this._config.privateKeyFilePath) {
321-
this._authHandler.privateKeyAuth(
322-
nextAuth,
323-
this._config.privateKeyFilePath,
324-
this._config.username,
325-
);
338+
this._authHandler
339+
.privateKeyAuth(
340+
nextAuth,
341+
this._config.privateKeyFilePath,
342+
this._config.username,
343+
)
344+
.catch((e) => {
345+
this._reject?.(e);
346+
return false;
347+
});
326348
} else if (process.env.SSH_AUTH_SOCK) {
327349
this._authHandler.sshAgentAuth(nextAuth, this._config.username);
328350
}
329351
break;
330352
}
331353
case "password": {
332-
this._authHandler.passwordAuth(nextAuth, this._config.username);
354+
this._authHandler
355+
.passwordAuth(nextAuth, this._config.username)
356+
.catch((e) => {
357+
this._reject?.(e);
358+
return false;
359+
});
333360
break;
334361
}
335362
case "keyboard-interactive": {
336-
this._authHandler.keyboardInteractiveAuth(
337-
nextAuth,
338-
this._config.username,
339-
);
363+
this._authHandler
364+
.keyboardInteractiveAuth(nextAuth, this._config.username)
365+
.catch((e) => {
366+
this._reject?.(e);
367+
return false;
368+
});
340369
break;
341370
}
342371
default:

0 commit comments

Comments
 (0)