Skip to content

Commit 9e6b773

Browse files
chore: add unlink to unix socket forwarding
Co-authored-by: Samuel Corsi-House <[email protected]>
1 parent 07e1ffa commit 9e6b773

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

streamlocal.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package ssh
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"io/fs"
68
"net"
79
"os"
810
"path/filepath"
911
"sync"
12+
"syscall"
1013

1114
gossh "golang.org/x/crypto/ssh"
1215
)
@@ -128,6 +131,16 @@ func (h *ForwardedUnixHandler) HandleSSHRequest(ctx Context, srv *Server, req *g
128131
return false, nil
129132
}
130133

134+
// Remove existing socket if it exists. We do not use os.Remove() here
135+
// so that directories are kept. Note that it's possible that we will
136+
// overwrite a regular file here. Both of these behaviors match OpenSSH,
137+
// however, which is why we unlink.
138+
err = unlink(addr)
139+
if err != nil && !errors.Is(err, fs.ErrNotExist) {
140+
// TODO: log unlink failure
141+
return false, nil
142+
}
143+
131144
ln, err := net.Listen("unix", addr)
132145
if err != nil {
133146
// TODO: log unix listen failure
@@ -202,3 +215,15 @@ func (h *ForwardedUnixHandler) HandleSSHRequest(ctx Context, srv *Server, req *g
202215
return false, nil
203216
}
204217
}
218+
219+
// unlink removes files and unlike os.Remove, directories are kept.
220+
func unlink(path string) error {
221+
// Ignore EINTR like os.Remove, see ignoringEINTR in os/file_posix.go
222+
// for more details.
223+
for {
224+
err := syscall.Unlink(path)
225+
if !errors.Is(err, syscall.EINTR) {
226+
return err
227+
}
228+
}
229+
}

0 commit comments

Comments
 (0)