From f8f256354f953d6a3cb01422a3babc4e3455e31f Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Tue, 6 Feb 2018 16:53:26 -0800 Subject: [PATCH] use winrmcp logic when creating new winrm client for uploads and downloads --- communicator/winrm/communicator.go | 52 ++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/communicator/winrm/communicator.go b/communicator/winrm/communicator.go index 3970d1af8..6cf2bce37 100644 --- a/communicator/winrm/communicator.go +++ b/communicator/winrm/communicator.go @@ -128,12 +128,10 @@ func (c *Communicator) Upload(path string, input io.Reader, fi *os.FileInfo) err return err } - // Get information about destination path - endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout) - client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password) if err != nil { return fmt.Errorf("Was unable to create winrm client: %s", err) } + client, err := c.newWinRMClient() stdout, _, _, err := client.RunWithString(fmt.Sprintf("powershell -Command \"(Get-Item %s) -is [System.IO.DirectoryInfo]\"", path), "") if err != nil { return fmt.Errorf("Couldn't determine whether destination was a folder or file: %s", err) @@ -162,8 +160,7 @@ func (c *Communicator) UploadDir(dst string, src string, exclude []string) error } func (c *Communicator) Download(src string, dst io.Writer) error { - endpoint := winrm.NewEndpoint(c.endpoint.Host, c.endpoint.Port, c.config.Https, c.config.Insecure, nil, nil, nil, c.config.Timeout) - client, err := winrm.NewClient(endpoint, c.config.Username, c.config.Password) + client, err := c.newWinRMClient() if err != nil { return err } @@ -182,9 +179,8 @@ func (c *Communicator) DownloadDir(src string, dst string, exclude []string) err return fmt.Errorf("WinRM doesn't support download dir.") } -func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { - addr := fmt.Sprintf("%s:%d", c.endpoint.Host, c.endpoint.Port) - return winrmcp.New(addr, &winrmcp.Config{ +func (c *Communicator) getClientConfig() *winrmcp.Config { + return &winrmcp.Config{ Auth: winrmcp.Auth{ User: c.config.Username, Password: c.config.Password, @@ -194,7 +190,45 @@ func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { OperationTimeout: c.config.Timeout, MaxOperationsPerShell: 15, // lowest common denominator TransportDecorator: c.config.TransportDecorator, - }) + } +} + +func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) { + addr := fmt.Sprintf("%s:%d", c.endpoint.Host, c.endpoint.Port) + clientConfig := c.getClientConfig() + return winrmcp.New(addr, clientConfig) +} + +func (c *Communicator) newWinRMClient() (*winrm.Client, error) { + conf := c.getClientConfig() + + // Shamelessly borrowed from the winrmcp client to ensure + // that the client is configured using the same defaulting behaviors that + // winrmcp uses even we we aren't using winrmcp. This ensures similar + // behavior between upload, download, and copy functions. We can't use the + // one generated by winrmcp because it isn't exported. + var endpoint *winrm.Endpoint + endpoint = &winrm.Endpoint{ + Host: c.endpoint.Host, + Port: c.endpoint.Port, + HTTPS: conf.Https, + Insecure: conf.Insecure, + TLSServerName: conf.TLSServerName, + CACert: conf.CACertBytes, + Timeout: conf.ConnectTimeout, + } + params := winrm.NewParameters( + winrm.DefaultParameters.Timeout, + winrm.DefaultParameters.Locale, + winrm.DefaultParameters.EnvelopeSize, + ) + + params.TransportDecorator = conf.TransportDecorator + params.Timeout = "PT3M" + + client, err := winrm.NewClientWithParameters( + endpoint, conf.Auth.User, conf.Auth.Password, params) + return client, err } type Base64Pipe struct {