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,32 @@ 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 is not JetBrains, then we do not need to do anything special. We
44
+ // attempt to match on something that appears unique to JetBrains software and
45
+ // the vendor name flag seems like it might be a reasonable choice.
46
+ if strings .Contains (strings .ToLower (name ), "idea.vendor.name=jetbrains" ) {
47
+ return newChannel
48
+ }
49
+
50
+ logger .Debug (ctx , "discovered forwarded JetBrains process" ,
51
+ slog .F ("destination_port" , d .DestPort ))
35
52
36
53
return & ChannelAcceptWatcher {
37
54
NewChannel : newChannel ,
0 commit comments