Skip to content

Commit df77a2b

Browse files
committed
fix(agent/agentssh): use configured directory for SFTP connections
Previously, SFTP connections always landed in the user's home directory, ignoring the agent's configured working directory. This was inconsistent with SSH sessions and rsync, which respected the configured directory. Now SFTP connections use the same logic: check the configured working directory first, falling back to home directory only when not set.
1 parent 84760f4 commit df77a2b

File tree

2 files changed

+83
-42
lines changed

2 files changed

+83
-42
lines changed

agent/agent_test.go

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -994,42 +994,77 @@ func TestAgent_UnixRemoteForwarding(t *testing.T) {
994994

995995
func TestAgent_SFTP(t *testing.T) {
996996
t.Parallel()
997-
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
998-
defer cancel()
999-
u, err := user.Current()
1000-
require.NoError(t, err, "get current user")
1001-
home := u.HomeDir
1002-
if runtime.GOOS == "windows" {
1003-
home = "/" + strings.ReplaceAll(home, "\\", "/")
1004-
}
1005-
//nolint:dogsled
1006-
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
1007-
sshClient, err := conn.SSHClient(ctx)
1008-
require.NoError(t, err)
1009-
defer sshClient.Close()
1010-
client, err := sftp.NewClient(sshClient)
1011-
require.NoError(t, err)
1012-
defer client.Close()
1013-
wd, err := client.Getwd()
1014-
require.NoError(t, err, "get working directory")
1015-
require.Equal(t, home, wd, "working directory should be home user home")
1016-
tempFile := filepath.Join(t.TempDir(), "sftp")
1017-
// SFTP only accepts unix-y paths.
1018-
remoteFile := filepath.ToSlash(tempFile)
1019-
if !path.IsAbs(remoteFile) {
1020-
// On Windows, e.g. "/C:/Users/...".
1021-
remoteFile = path.Join("/", remoteFile)
1022-
}
1023-
file, err := client.Create(remoteFile)
1024-
require.NoError(t, err)
1025-
err = file.Close()
1026-
require.NoError(t, err)
1027-
_, err = os.Stat(tempFile)
1028-
require.NoError(t, err)
1029997

1030-
// Close the client to trigger disconnect event.
1031-
_ = client.Close()
1032-
assertConnectionReport(t, agentClient, proto.Connection_SSH, 0, "")
998+
t.Run("DefaultWorkingDirectory", func(t *testing.T) {
999+
t.Parallel()
1000+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
1001+
defer cancel()
1002+
u, err := user.Current()
1003+
require.NoError(t, err, "get current user")
1004+
home := u.HomeDir
1005+
if runtime.GOOS == "windows" {
1006+
home = "/" + strings.ReplaceAll(home, "\\", "/")
1007+
}
1008+
//nolint:dogsled
1009+
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
1010+
sshClient, err := conn.SSHClient(ctx)
1011+
require.NoError(t, err)
1012+
defer sshClient.Close()
1013+
client, err := sftp.NewClient(sshClient)
1014+
require.NoError(t, err)
1015+
defer client.Close()
1016+
wd, err := client.Getwd()
1017+
require.NoError(t, err, "get working directory")
1018+
require.Equal(t, home, wd, "working directory should be user home")
1019+
tempFile := filepath.Join(t.TempDir(), "sftp")
1020+
// SFTP only accepts unix-y paths.
1021+
remoteFile := filepath.ToSlash(tempFile)
1022+
if !path.IsAbs(remoteFile) {
1023+
// On Windows, e.g. "/C:/Users/...".
1024+
remoteFile = path.Join("/", remoteFile)
1025+
}
1026+
file, err := client.Create(remoteFile)
1027+
require.NoError(t, err)
1028+
err = file.Close()
1029+
require.NoError(t, err)
1030+
_, err = os.Stat(tempFile)
1031+
require.NoError(t, err)
1032+
1033+
// Close the client to trigger disconnect event.
1034+
_ = client.Close()
1035+
assertConnectionReport(t, agentClient, proto.Connection_SSH, 0, "")
1036+
})
1037+
1038+
t.Run("CustomWorkingDirectory", func(t *testing.T) {
1039+
t.Parallel()
1040+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
1041+
defer cancel()
1042+
1043+
// Create a custom directory for the agent to use.
1044+
customDir := t.TempDir()
1045+
expectedDir := customDir
1046+
if runtime.GOOS == "windows" {
1047+
expectedDir = "/" + strings.ReplaceAll(customDir, "\\", "/")
1048+
}
1049+
1050+
//nolint:dogsled
1051+
conn, agentClient, _, _, _ := setupAgent(t, agentsdk.Manifest{
1052+
Directory: customDir,
1053+
}, 0)
1054+
sshClient, err := conn.SSHClient(ctx)
1055+
require.NoError(t, err)
1056+
defer sshClient.Close()
1057+
client, err := sftp.NewClient(sshClient)
1058+
require.NoError(t, err)
1059+
defer client.Close()
1060+
wd, err := client.Getwd()
1061+
require.NoError(t, err, "get working directory")
1062+
require.Equal(t, expectedDir, wd, "working directory should be custom directory")
1063+
1064+
// Close the client to trigger disconnect event.
1065+
_ = client.Close()
1066+
assertConnectionReport(t, agentClient, proto.Connection_SSH, 0, "")
1067+
})
10331068
}
10341069

10351070
func TestAgent_SCP(t *testing.T) {

agent/agentssh/agentssh.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -829,13 +829,19 @@ func (s *Server) sftpHandler(logger slog.Logger, session ssh.Session) error {
829829
session.DisablePTYEmulation()
830830

831831
var opts []sftp.ServerOption
832-
// Change current working directory to the users home
833-
// directory so that SFTP connections land there.
834-
homedir, err := userHomeDir()
835-
if err != nil {
836-
logger.Warn(ctx, "get sftp working directory failed, unable to get home dir", slog.Error(err))
837-
} else {
838-
opts = append(opts, sftp.WithServerWorkingDirectory(homedir))
832+
// Change current working directory to the configured
833+
// directory (or home directory if not set) so that SFTP
834+
// connections land there.
835+
dir := s.config.WorkingDirectory()
836+
if dir == "" {
837+
var err error
838+
dir, err = userHomeDir()
839+
if err != nil {
840+
logger.Warn(ctx, "get sftp working directory failed, unable to get home dir", slog.Error(err))
841+
}
842+
}
843+
if dir != "" {
844+
opts = append(opts, sftp.WithServerWorkingDirectory(dir))
839845
}
840846

841847
server, err := sftp.NewServer(session, opts...)

0 commit comments

Comments
 (0)