Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f017548

Browse files
authored
fix: Return correct exit code for SFTP sessions (#5044)
Fixes #5038
1 parent 2a6fff9 commit f017548

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

agent/agent.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,12 @@ func (a *agent) init(ctx context.Context) {
476476
},
477477
SubsystemHandlers: map[string]ssh.SubsystemHandler{
478478
"sftp": func(session ssh.Session) {
479+
ctx := session.Context()
480+
481+
// Typically sftp sessions don't request a TTY, but if they do,
482+
// we must ensure the gliderlabs/ssh CRLF emulation is disabled.
483+
// Otherwise sftp will be broken. This can happen if a user sets
484+
// `RequestTTY force` in their SSH config.
479485
session.DisablePTYEmulation()
480486

481487
var opts []sftp.ServerOption
@@ -484,22 +490,33 @@ func (a *agent) init(ctx context.Context) {
484490
// https://github.com/coder/coder/issues/3620
485491
u, err := user.Current()
486492
if err != nil {
487-
a.logger.Warn(ctx, "get sftp working directory failed, unable to get current user", slog.Error(err))
493+
sshLogger.Warn(ctx, "get sftp working directory failed, unable to get current user", slog.Error(err))
488494
} else {
489495
opts = append(opts, sftp.WithServerWorkingDirectory(u.HomeDir))
490496
}
491497

492498
server, err := sftp.NewServer(session, opts...)
493499
if err != nil {
494-
a.logger.Debug(session.Context(), "initialize sftp server", slog.Error(err))
500+
sshLogger.Debug(ctx, "initialize sftp server", slog.Error(err))
495501
return
496502
}
497503
defer server.Close()
504+
498505
err = server.Serve()
499506
if errors.Is(err, io.EOF) {
507+
// Unless we call `session.Exit(0)` here, the client won't
508+
// receive `exit-status` because `(*sftp.Server).Close()`
509+
// calls `Close()` on the underlying connection (session),
510+
// which actually calls `channel.Close()` because it isn't
511+
// wrapped. This causes sftp clients to receive a non-zero
512+
// exit code. Typically sftp clients don't echo this exit
513+
// code but `scp` on macOS does (when using the default
514+
// SFTP backend).
515+
_ = session.Exit(0)
500516
return
501517
}
502-
a.logger.Debug(session.Context(), "sftp server exited with error", slog.Error(err))
518+
sshLogger.Warn(ctx, "sftp server closed with error", slog.Error(err))
519+
_ = session.Exit(1)
503520
},
504521
},
505522
}

0 commit comments

Comments
 (0)