1
1
package agentssh
2
2
3
3
import (
4
+ "context"
4
5
"encoding/binary"
5
6
"encoding/hex"
6
7
"errors"
@@ -9,8 +10,10 @@ import (
9
10
"os"
10
11
"path/filepath"
11
12
"strconv"
13
+ "time"
12
14
13
15
"github.com/gliderlabs/ssh"
16
+ "github.com/gofrs/flock"
14
17
"github.com/spf13/afero"
15
18
gossh "golang.org/x/crypto/ssh"
16
19
"golang.org/x/xerrors"
@@ -20,16 +23,22 @@ import (
20
23
21
24
// x11Callback is called when the client requests X11 forwarding.
22
25
// It adds an Xauthority entry to the Xauthority file.
23
- func x11Callback ( logger slog. Logger , fs afero. Fs , ctx ssh.Context , x11 ssh.X11 ) bool {
26
+ func ( s * Server ) x11Callback ( ctx ssh.Context , x11 ssh.X11 ) bool {
24
27
hostname , err := os .Hostname ()
25
28
if err != nil {
26
- logger .Warn (ctx , "failed to get hostname" , slog .Error (err ))
29
+ s . logger .Warn (ctx , "failed to get hostname" , slog .Error (err ))
27
30
return false
28
31
}
29
32
30
- err = addXauthEntry ( fs , hostname , strconv . Itoa ( int ( x11 . ScreenNumber )), x11 . AuthProtocol , x11 . AuthCookie )
33
+ err = s . fs . MkdirAll ( s . x11SocketDir , 0o700 )
31
34
if err != nil {
32
- logger .Warn (ctx , "failed to add Xauthority entry" , slog .Error (err ))
35
+ s .logger .Warn (ctx , "failed to make the x11 socket dir" , slog .F ("dir" , s .x11SocketDir ), slog .Error (err ))
36
+ return false
37
+ }
38
+
39
+ err = addXauthEntry (ctx , s .fs , hostname , strconv .Itoa (int (x11 .ScreenNumber )), x11 .AuthProtocol , x11 .AuthCookie )
40
+ if err != nil {
41
+ s .logger .Warn (ctx , "failed to add Xauthority entry" , slog .Error (err ))
33
42
return false
34
43
}
35
44
return true
@@ -64,16 +73,16 @@ func (s *Server) x11Handler(ctx ssh.Context, x11 ssh.X11) bool {
64
73
}
65
74
unixConn , ok := conn .(* net.UnixConn )
66
75
if ! ok {
67
- s .logger .Warn (ctx , "failed to cast connection to UnixConn" )
76
+ s .logger .Warn (ctx , fmt . Sprintf ( "failed to cast connection to UnixConn. got: %T" , conn ) )
68
77
return
69
78
}
70
79
unixAddr , ok := unixConn .LocalAddr ().(* net.UnixAddr )
71
80
if ! ok {
72
- s .logger .Warn (ctx , "failed to cast local address to UnixAddr" )
81
+ s .logger .Warn (ctx , fmt . Sprintf ( "failed to cast local address to UnixAddr. got: %T" , unixConn . LocalAddr ()) )
73
82
return
74
83
}
75
84
76
- channel , _ , err := serverConn .OpenChannel ("x11" , gossh .Marshal (struct {
85
+ channel , reqs , err := serverConn .OpenChannel ("x11" , gossh .Marshal (struct {
77
86
OriginatorAddress string
78
87
OriginatorPort uint32
79
88
}{
@@ -84,7 +93,7 @@ func (s *Server) x11Handler(ctx ssh.Context, x11 ssh.X11) bool {
84
93
s .logger .Warn (ctx , "failed to open X11 channel" , slog .Error (err ))
85
94
return
86
95
}
87
-
96
+ go gossh . DiscardRequests ( reqs )
88
97
go Bicopy (ctx , conn , channel )
89
98
}
90
99
}()
@@ -93,7 +102,7 @@ func (s *Server) x11Handler(ctx ssh.Context, x11 ssh.X11) bool {
93
102
94
103
// addXauthEntry adds an Xauthority entry to the Xauthority file.
95
104
// The Xauthority file is located at ~/.Xauthority.
96
- func addXauthEntry (fs afero.Fs , host string , display string , authProtocol string , authCookie string ) error {
105
+ func addXauthEntry (ctx context. Context , fs afero.Fs , host string , display string , authProtocol string , authCookie string ) error {
97
106
// Get the Xauthority file path
98
107
homeDir , err := os .UserHomeDir ()
99
108
if err != nil {
@@ -102,8 +111,15 @@ func addXauthEntry(fs afero.Fs, host string, display string, authProtocol string
102
111
103
112
xauthPath := filepath .Join (homeDir , ".Xauthority" )
104
113
114
+ lock := flock .New (xauthPath )
115
+ ok , err := lock .TryLockContext (ctx , 100 * time .Millisecond )
116
+ if ! ok {
117
+ return xerrors .Errorf ("failed to lock Xauthority file: %w" , err )
118
+ }
119
+ defer lock .Close ()
120
+
105
121
// Open or create the Xauthority file
106
- file , err := fs .OpenFile (xauthPath , os .O_RDWR | os .O_CREATE | os .O_APPEND , 0600 )
122
+ file , err := fs .OpenFile (xauthPath , os .O_RDWR | os .O_CREATE | os .O_APPEND , 0o600 )
107
123
if err != nil {
108
124
return xerrors .Errorf ("failed to open Xauthority file: %w" , err )
109
125
}
0 commit comments