MCPcopy Index your code
hub / github.com/coder/coder / HandleSSHRequest

Method HandleSSHRequest

agent/agentssh/forward.go:56–212  ·  view source on GitHub ↗
(ctx ssh.Context, _ *ssh.Server, req *gossh.Request)

Source from the content-addressed store, hash-verified

54}
55
56func (h *forwardedUnixHandler) HandleSSHRequest(ctx ssh.Context, _ *ssh.Server, req *gossh.Request) (bool, []byte) {
57 h.log.Debug(ctx, "handling SSH unix forward")
58 conn, ok := ctx.Value(ssh.ContextKeyConn).(*gossh.ServerConn)
59 if !ok {
60 h.log.Warn(ctx, "SSH unix forward request from client with no gossh connection")
61 return false, nil
62 }
63 log := h.log.With(slog.F("session_id", ctx.SessionID()), slog.F("remote_addr", conn.RemoteAddr()))
64
65 switch req.Type {
66 case "streamlocal-forward@openssh.com":
67 if h.blockReversePortForwarding {
68 log.Warn(ctx, "unix reverse port forward blocked")
69 return false, nil
70 }
71 var reqPayload streamLocalForwardPayload
72 err := gossh.Unmarshal(req.Payload, &reqPayload)
73 if err != nil {
74 h.log.Warn(ctx, "parse streamlocal-forward@openssh.com request (SSH unix forward) payload from client", slog.Error(err))
75 return false, nil
76 }
77
78 addr := reqPayload.SocketPath
79 log = log.With(slog.F("socket_path", addr))
80 log.Debug(ctx, "request begin SSH unix forward")
81
82 key := forwardKey{
83 sessionID: ctx.SessionID(),
84 addr: addr,
85 }
86
87 h.Lock()
88 _, ok := h.forwards[key]
89 h.Unlock()
90 if ok {
91 // In cases where `ExitOnForwardFailure=yes` is set, returning false
92 // here will cause the connection to be closed. To avoid this, and
93 // to match OpenSSH behavior, we silently ignore the second forward
94 // request.
95 log.Warn(ctx, "SSH unix forward request for socket path that is already being forwarded on this session, ignoring")
96 return true, nil
97 }
98
99 // Create socket parent dir if not exists.
100 parentDir := filepath.Dir(addr)
101 err = os.MkdirAll(parentDir, 0o700)
102 if err != nil {
103 log.Warn(ctx, "create parent dir for SSH unix forward request",
104 slog.F("parent_dir", parentDir),
105 slog.Error(err),
106 )
107 return false, nil
108 }
109
110 // Remove existing socket if it exists. We do not use os.Remove() here
111 // so that directories are kept. Note that it's possible that we will
112 // overwrite a regular file here. Both of these behaviors match OpenSSH,
113 // however, which is why we unlink.

Callers

nothing calls this directly

Calls 15

unlinkFunction · 0.85
BicopyFunction · 0.85
SessionIDMethod · 0.80
MkdirAllMethod · 0.80
ListenMethod · 0.65
CloseMethod · 0.65
ValueMethod · 0.45
RemoteAddrMethod · 0.45
UnmarshalMethod · 0.45
ErrorMethod · 0.45
LockMethod · 0.45
UnlockMethod · 0.45

Tested by

no test coverage detected