1
1
package agentssh
2
2
3
3
import (
4
+ "strings"
4
5
"sync"
5
6
6
7
"cdr.dev/slog"
8
+ "github.com/gliderlabs/ssh"
7
9
"go.uber.org/atomic"
8
10
gossh "golang.org/x/crypto/ssh"
9
11
)
@@ -21,17 +23,31 @@ type ChannelAcceptWatcher struct {
21
23
jetbrainsCounter * atomic.Int64
22
24
}
23
25
24
- func NewChannelAcceptWatcher (logger slog.Logger , newChannel gossh.NewChannel , counter * atomic.Int64 ) gossh.NewChannel {
26
+ func NewChannelAcceptWatcher (ctx ssh. Context , logger slog.Logger , newChannel gossh.NewChannel , counter * atomic.Int64 ) gossh.NewChannel {
25
27
d := localForwardChannelData {}
26
28
if err := gossh .Unmarshal (newChannel .ExtraData (), & d ); err != nil {
27
- // If the data fails to unmarshal, do nothing
29
+ // If the data fails to unmarshal, do nothing.
28
30
return newChannel
29
31
}
30
32
31
- //if !jetbrains {
32
- // If this isn't jetbrains, then we don't need to do anything special.
33
- //return newChannel
34
- //}
33
+ // If we do get a port, we should be able to get the matching PID and from
34
+ // there look up the name
35
+ name , err := getListeningPortProcessName (d .DestPort )
36
+ if err != nil {
37
+ logger .Warn (ctx , "port inspection failed" ,
38
+ slog .F ("destination_port" , d .DestPort ),
39
+ slog .Error (err ))
40
+ return newChannel
41
+ }
42
+
43
+ // If this isn't JetBrains, then we don't need to do anything special. We
44
+ // attempt to match on something that appears unique to JetBrains software.
45
+ if strings .Contains (strings .ToLower (name ), "idea.vendor.name=jetbrains" ) {
46
+ return newChannel
47
+ }
48
+
49
+ logger .Debug (ctx , "discovered forwarded JetBrains process" ,
50
+ slog .F ("destination_port" , d .DestPort ))
35
51
36
52
return & ChannelAcceptWatcher {
37
53
NewChannel : newChannel ,
0 commit comments