Skip to content

Commit e5b4ca1

Browse files
mustard-mhjeanp413
andauthored
Close conn based on piped conn IDE-50 (#50)
* Close conn based on piped conn IDE-50 * Close session after auth failed * 💄 --------- Co-authored-by: Jean Pierre <[email protected]>
1 parent 829a815 commit e5b4ca1

File tree

4 files changed

+28
-24
lines changed

4 files changed

+28
-24
lines changed

src/daemonStarter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ export async function tryStartDaemon(logService: ILogService, options?: Partial<
6161
const daemon = spawn(process.execPath, args, {
6262
detached: true,
6363
stdio: 'ignore',
64-
env: process.env
64+
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
6565
});
6666
daemon.unref();
6767
return daemon;
68-
}
68+
}

src/local-ssh/ipc/localssh.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ export class LocalSSHServiceImpl implements LocalSSHServiceImplementation {
8181
}
8282

8383
public async getWorkspaceAuthInfo(workspaceId: string) {
84-
return retryWithStop(async (stop) => {
85-
const getAuthInfo = async (id: string, client: Client<ExtensionServiceDefinition>) => {
84+
return retryWithStop((stop) => {
85+
const getAuthInfo = (id: string, client: Client<ExtensionServiceDefinition>) => {
8686
try {
87-
return await client.getWorkspaceAuthInfo({ workspaceId });
87+
return client.getWorkspaceAuthInfo({ workspaceId });
8888
} catch (e) {
8989
if (e instanceof ServerError) {
9090
if (e.code === Status.UNAVAILABLE && e.details.startsWith('workspace is not running')) {
@@ -95,7 +95,7 @@ export class LocalSSHServiceImpl implements LocalSSHServiceImplementation {
9595
throw e;
9696
}
9797
};
98-
return await Promise.any(this.extensionServices.map(ext => getAuthInfo(ext.id, ext.client)));
98+
return Promise.any(this.extensionServices.map(ext => getAuthInfo(ext.id, ext.client)));
9999
}, 200, 3);
100100
}
101101

src/local-ssh/logger.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66
import winston from 'winston';
77
import { ILogService } from '../services/logService';
88

9-
export enum ExitCode {
10-
OK = 0,
11-
ListenPortFailed = 100,
12-
UnexpectedError = 101,
13-
InvalidOptions = 102,
14-
}
15-
169
const DefaultLogFormatter = winston.format.combine(winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.simple());
10+
1711
export class Logger implements ILogService {
1812
private logger: winston.Logger;
1913

@@ -47,4 +41,4 @@ export class Logger implements ILogService {
4741
show(): void {
4842
// no-op
4943
}
50-
}
44+
}

src/local-ssh/server.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { LocalSSHServiceImpl, startLocalSSHService } from './ipc/localssh';
99
import { SupervisorSSHTunnel } from './sshTunnel';
1010
import { ILogService } from '../services/logService';
1111
import { SshServer, SshClient } from '@microsoft/dev-tunnels-ssh-tcp';
12-
import { NodeStream, SshClientCredentials, SshClientSession, SshSessionConfiguration } from '@microsoft/dev-tunnels-ssh';
12+
import { NodeStream, SshClientCredentials, SshClientSession, SshDisconnectReason, SshSessionConfiguration } from '@microsoft/dev-tunnels-ssh';
1313
import { importKeyBytes } from '@microsoft/dev-tunnels-ssh-keys';
1414
import { parsePrivateKey } from 'sshpk';
1515
import { PipeExtensions } from './patch/pipeExtension';
@@ -23,14 +23,15 @@ export class LocalSSHGatewayServer {
2323
private localsshService!: LocalSSHServiceImpl;
2424
private localsshServiceServer?: GrpcServer;
2525
private server?: SshServer;
26+
private clientCount = 0;
2627

2728
constructor(
2829
private readonly logger: ILogService,
2930
private readonly port: number,
3031
private readonly ipcPort: number,
3132
) { }
3233

33-
async authenticateClient(clientUsername: string) {
34+
private async authenticateClient(clientUsername: string) {
3435
const workspaceInfo = await this.localsshService.getWorkspaceAuthInfo(clientUsername).catch(e => {
3536
this.logger.error(e, 'failed to get workspace auth info');
3637
/*
@@ -69,22 +70,32 @@ export class LocalSSHGatewayServer {
6970

7071
server.onSessionOpened((session) => {
7172
let pipeSession: SshClientSession;
73+
this.clientCount += 1;
7274
session.onAuthenticating((e) => {
73-
e.authenticationPromise = new Promise((resolve, reject) => {
74-
this.authenticateClient(e.username!).then(async s => {
75+
e.authenticationPromise = this.authenticateClient(e.username!).then(s => {
7576
this.logger.info('authenticate with ' + e.username);
7677
pipeSession = s;
77-
resolve(new Object());
78+
return {};
7879
}).catch(e => {
7980
this.logger.error(e, 'failed to authenticate client');
8081
// TODO not sure how to get gitpod host here
8182
// this.localsshService.sendErrorReport(e.username, undefined, e, 'failed to authenticate client');
82-
reject(null);
83+
session.close(SshDisconnectReason.hostNotAllowedToConnect, 'auth failed or workspace is not running');
84+
return null;
8385
});
84-
});
8586
});
86-
session.onClientAuthenticated(() => {
87-
PipeExtensions.pipeSession(session, pipeSession);
87+
session.onClientAuthenticated(async () => {
88+
try {
89+
await PipeExtensions.pipeSession(session, pipeSession);
90+
} catch (e) {
91+
this.logger.error(e, 'pipe session ended with error');
92+
} finally {
93+
session.close(SshDisconnectReason.connectionLost, 'pipe session ended');
94+
}
95+
});
96+
session.onClosed(() => {
97+
this.clientCount -= 1;
98+
this.logger.debug('current connecting client count: ' + this.clientCount);
8899
});
89100
});
90101
await server.acceptSessions(this.port, '127.0.0.1');
@@ -180,4 +191,3 @@ export class LocalSSHGatewayServer {
180191
this.localsshServiceServer?.shutdown();
181192
}
182193
}
183-

0 commit comments

Comments
 (0)