@@ -9,7 +9,7 @@ import { LocalSSHServiceImpl, startLocalSSHService } from './ipc/localssh';
9
9
import { SupervisorSSHTunnel } from './sshTunnel' ;
10
10
import { ILogService } from '../services/logService' ;
11
11
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' ;
13
13
import { importKeyBytes } from '@microsoft/dev-tunnels-ssh-keys' ;
14
14
import { parsePrivateKey } from 'sshpk' ;
15
15
import { PipeExtensions } from './patch/pipeExtension' ;
@@ -23,14 +23,15 @@ export class LocalSSHGatewayServer {
23
23
private localsshService ! : LocalSSHServiceImpl ;
24
24
private localsshServiceServer ?: GrpcServer ;
25
25
private server ?: SshServer ;
26
+ private clientCount = 0 ;
26
27
27
28
constructor (
28
29
private readonly logger : ILogService ,
29
30
private readonly port : number ,
30
31
private readonly ipcPort : number ,
31
32
) { }
32
33
33
- async authenticateClient ( clientUsername : string ) {
34
+ private async authenticateClient ( clientUsername : string ) {
34
35
const workspaceInfo = await this . localsshService . getWorkspaceAuthInfo ( clientUsername ) . catch ( e => {
35
36
this . logger . error ( e , 'failed to get workspace auth info' ) ;
36
37
/*
@@ -69,22 +70,32 @@ export class LocalSSHGatewayServer {
69
70
70
71
server . onSessionOpened ( ( session ) => {
71
72
let pipeSession : SshClientSession ;
73
+ this . clientCount += 1 ;
72
74
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 => {
75
76
this . logger . info ( 'authenticate with ' + e . username ) ;
76
77
pipeSession = s ;
77
- resolve ( new Object ( ) ) ;
78
+ return { } ;
78
79
} ) . catch ( e => {
79
80
this . logger . error ( e , 'failed to authenticate client' ) ;
80
81
// TODO not sure how to get gitpod host here
81
82
// 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 ;
83
85
} ) ;
84
- } ) ;
85
86
} ) ;
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 ) ;
88
99
} ) ;
89
100
} ) ;
90
101
await server . acceptSessions ( this . port , '127.0.0.1' ) ;
@@ -180,4 +191,3 @@ export class LocalSSHGatewayServer {
180
191
this . localsshServiceServer ?. shutdown ( ) ;
181
192
}
182
193
}
183
-
0 commit comments