From 714632206c7bd4473af7dacc15132ebf2cbefe03 Mon Sep 17 00:00:00 2001 From: Bryan Eastes Date: Tue, 15 Jun 2021 10:04:01 -0700 Subject: [PATCH] Quoting filesystem path in scp command argument (#28626) * Quoting filesystem path in scp command argument * Adding proper shell quoting for scp commands * Running go fmt * Using a library for quoting shell commands * Don't export quoteShell function --- internal/communicator/ssh/communicator.go | 25 +++++++++++++++++-- .../communicator/ssh/communicator_test.go | 6 ++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/internal/communicator/ssh/communicator.go b/internal/communicator/ssh/communicator.go index f312540214..4de6a90408 100644 --- a/internal/communicator/ssh/communicator.go +++ b/internal/communicator/ssh/communicator.go @@ -18,6 +18,7 @@ import ( "sync" "time" + "github.com/apparentlymart/go-shquot/shquot" "github.com/hashicorp/errwrap" "github.com/hashicorp/terraform/internal/communicator/remote" "github.com/hashicorp/terraform/internal/provisioners" @@ -419,7 +420,11 @@ func (c *Communicator) Upload(path string, input io.Reader) error { return scpUploadFile(targetFile, input, w, stdoutR, size) } - return c.scpSession("scp -vt "+targetDir, scpFunc) + cmd, err := quoteShell([]string{"scp", "-vt", targetDir}, c.connInfo.TargetPlatform) + if err != nil { + return err + } + return c.scpSession(cmd, scpFunc) } // UploadScript implementation of communicator.Communicator interface @@ -488,7 +493,11 @@ func (c *Communicator) UploadDir(dst string, src string) error { return uploadEntries() } - return c.scpSession("scp -rvt "+dst, scpFunc) + cmd, err := quoteShell([]string{"scp", "-rvt", dst}, c.connInfo.TargetPlatform) + if err != nil { + return err + } + return c.scpSession(cmd, scpFunc) } func (c *Communicator) newSession() (session *ssh.Session, err error) { @@ -816,3 +825,15 @@ func (c *bastionConn) Close() error { c.Conn.Close() return c.Bastion.Close() } + +func quoteShell(args []string, targetPlatform string) (string, error) { + if targetPlatform == TargetPlatformUnix { + return shquot.POSIXShell(args), nil + } + if targetPlatform == TargetPlatformWindows { + return shquot.WindowsArgv(args), nil + } + + return "", fmt.Errorf("Cannot quote shell command, target platform unknown: %s", targetPlatform) + +} diff --git a/internal/communicator/ssh/communicator_test.go b/internal/communicator/ssh/communicator_test.go index c0bbeba77c..3880a35606 100644 --- a/internal/communicator/ssh/communicator_test.go +++ b/internal/communicator/ssh/communicator_test.go @@ -642,7 +642,11 @@ func TestAccHugeUploadFile(t *testing.T) { return scpUploadFile(targetFile, source, w, stdoutR, size) } - err = c.scpSession("scp -vt "+targetDir, scpFunc) + cmd, err := quoteShell([]string{"scp", "-vt", targetDir}, c.connInfo.TargetPlatform) + if err != nil { + t.Fatal(err) + } + err = c.scpSession(cmd, scpFunc) if err != nil { t.Fatal(err) }