// Creates a new packer.Communicator implementation over WinRM.
// Called when Packer tries to connect to WinRM
func New(endpoint *winrm.Endpoint, user string, password string, timeout time.Duration) (*Communicator, error) {
	// Create the WinRM client we use internally
	params := winrm.DefaultParameters()
	params.Timeout = iso8601.FormatDuration(timeout)
	client, err := winrm.NewClientWithParameters(endpoint, user, password, params)
	if err != nil {
		return nil, err
	}

	// Attempt to connect to the WinRM service
	shell, err := client.CreateShell()
	if err != nil {
		return nil, err
	}

	err = shell.Close()
	if err != nil {
		return nil, err
	}

	return &Communicator{
		endpoint: endpoint,
		user:     user,
		password: password,
	}, nil
}
Ejemplo n.º 2
0
// Connect implementation of communicator.Communicator interface
func (c *Communicator) Connect(o terraform.UIOutput) error {
	if c.client != nil {
		return nil
	}

	params := winrm.DefaultParameters()
	params.Timeout = formatDuration(c.Timeout())

	client, err := winrm.NewClientWithParameters(
		c.endpoint, c.connInfo.User, c.connInfo.Password, params)
	if err != nil {
		return err
	}

	if o != nil {
		o.Output(fmt.Sprintf(
			"Connecting to remote host via WinRM...\n"+
				"  Host: %s\n"+
				"  Port: %d\n"+
				"  User: %s\n"+
				"  Password: %t\n"+
				"  HTTPS: %t\n"+
				"  Insecure: %t\n"+
				"  CACert: %t",
			c.connInfo.Host,
			c.connInfo.Port,
			c.connInfo.User,
			c.connInfo.Password != "",
			c.connInfo.HTTPS,
			c.connInfo.Insecure,
			c.connInfo.CACert != nil,
		))
	}

	log.Printf("connecting to remote shell using WinRM")
	shell, err := client.CreateShell()
	if err != nil {
		log.Printf("connection error: %s", err)
		return err
	}

	err = shell.Close()
	if err != nil {
		log.Printf("error closing connection: %s", err)
		return err
	}

	if o != nil {
		o.Output("Connected!")
	}

	c.client = client

	return nil
}
Ejemplo n.º 3
0
// New creates a new communicator implementation over WinRM.
func New(config *Config) (*Communicator, error) {
	endpoint := &winrm.Endpoint{
		Host:     config.Host,
		Port:     config.Port,
		HTTPS:    config.Https,
		Insecure: config.Insecure,

		/*
			TODO
			HTTPS:    connInfo.HTTPS,
			Insecure: connInfo.Insecure,
			CACert:   connInfo.CACert,
		*/
	}

	// Create the client
	params := winrm.DefaultParameters()

	if config.TransportDecorator != nil {
		params.TransportDecorator = config.TransportDecorator
	}

	params.Timeout = formatDuration(config.Timeout)
	client, err := winrm.NewClientWithParameters(
		endpoint, config.Username, config.Password, params)
	if err != nil {
		return nil, err
	}

	// Create the shell to verify the connection
	log.Printf("[DEBUG] connecting to remote shell using WinRM")
	shell, err := client.CreateShell()
	if err != nil {
		log.Printf("[ERROR] connection error: %s", err)
		return nil, err
	}

	if err := shell.Close(); err != nil {
		log.Printf("[ERROR] error closing connection: %s", err)
		return nil, err
	}

	return &Communicator{
		config:   config,
		client:   client,
		endpoint: endpoint,
	}, nil
}
Ejemplo n.º 4
0
func New(addr string, config *Config) (*Winrmcp, error) {
	endpoint, err := parseEndpoint(addr, config.Https, config.Insecure, config.CACertBytes)
	if err != nil {
		return nil, err
	}
	if config == nil {
		config = &Config{}
	}

	params := winrm.DefaultParameters()
	if config.OperationTimeout.Seconds() > 0 {
		params.Timeout = iso8601.FormatDuration(config.OperationTimeout)
	}
	client, err := winrm.NewClientWithParameters(
		endpoint, config.Auth.User, config.Auth.Password, params)
	return &Winrmcp{client, config}, err
}
Ejemplo n.º 5
0
func StartElevated() (err error) {
	// The command gets put into an interpolated string in the PS script,
	// so we need to escape any embedded quotes.
	cmd = strings.Replace(cmd, "\"", "`\"", -1)

	elevatedScript, err := createCommandText()

	if err != nil {
		return err
	}

	// Upload the script which creates and manages the scheduled task
	winrmcp, err := winrmcp.New(fmt.Sprintf("%s:%d", hostname, port), &winrmcp.Config{
		Auth:                  winrmcp.Auth{user, pass},
		OperationTimeout:      time.Second * 60,
		MaxOperationsPerShell: 15,
	})
	tmpFile, err := ioutil.TempFile(os.TempDir(), "packer-elevated-shell.ps1")
	log.Printf("Temp file: %s", tmpFile.Name())

	writer := bufio.NewWriter(tmpFile)
	if _, err := writer.WriteString(elevatedScript); err != nil {
		return fmt.Errorf("Error preparing shell script: %s", err)
	}

	if err := writer.Flush(); err != nil {
		return fmt.Errorf("Error preparing shell script: %s", err)
	}

	tmpFile.Close()

	err = winrmcp.Copy(tmpFile.Name(), "${env:TEMP}/packer-elevated-shell.ps1")

	if err != nil {
		log.Printf("Error copying shell script: %s", err)
		return err
	}

	// Run the script that was uploaded
	command := fmt.Sprintf("powershell -executionpolicy bypass -file \"%s\"", "%TEMP%\\packer-elevated-shell.ps1")
	log.Printf("Running script: %s", command)
	client, err = winrm.NewClientWithParameters(&winrm.Endpoint{Host: hostname, Port: port, HTTPS: false, Insecure: true, CACert: nil}, user, pass, winrm.NewParameters(timeout, "en-US", 153600))
	_, err = client.RunWithInput(command, os.Stdout, os.Stderr, os.Stdin)
	return err
}
Ejemplo n.º 6
0
func main() {

	flag.StringVar(&hostname, "hostname", "localhost", "winrm host")
	flag.StringVar(&user, "username", "vagrant", "winrm admin username")
	flag.StringVar(&pass, "password", "vagrant", "winrm admin password")
	flag.StringVar(&timeout, "timeout", "PT36000S", "winrm timeout")
	flag.IntVar(&port, "port", 5985, "winrm port")
	flag.BoolVar(&elevated, "elevated", false, "run as elevated user?")
	flag.BoolVar(&debug, "debug", false, "output debugging info")
	flag.Parse()

	cmdB, _ := ioutil.ReadAll(os.Stdin)
	cmd = string(cmdB)

	if !debug {
		log.SetOutput(ioutil.Discard)
	}

	log.Printf("Command to run: %s", cmd)
	log.Printf("user to run: %s", user)
	log.Printf("pass to run: %s", pass)
	log.Printf("host to run: %s", hostname)
	log.Printf("port to run: %s", port)
	client, err := winrm.NewClientWithParameters(&winrm.Endpoint{Host: hostname, Port: port, HTTPS: false, Insecure: true, CACert: nil}, user, pass, winrm.NewParameters(timeout, "en-US", 153600))

	if !elevated {
		_, err = client.RunWithInput(winrm.Powershell(cmd), os.Stdout, os.Stderr, os.Stdin)
	} else {
		err = StartElevated()
	}

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	os.Exit(0)
}
Ejemplo n.º 7
0
//
// WinRMRunCmdWithNTLM runs a command on a Windows Server (specifically
// an Azure VM with Windows). Uses WinRM with NTLM support enabled.
// WinRM should be enabled on the target server.
//
// Ref: https://github.com/masterzen/winrm/blob/master/README.md#pluggable-authentication-example-negotiatentlm-authentication
//
// Parameters:
//   host: target Windows server host
//   username: username for the host
//   password: password for the host
//   command: command to run
// Returns:
//   string: stdout from command execution
//   string: stderr from command execution
//   int:   exit status from the command being run
//   error: errors from establishing connection and running command
//
func WinRMRunCmdWithNTLM(host string, username string, password string, command string) (string, string, int, error) {
	var err error
	params := newwinrm.DefaultParameters()
	params.TransportDecorator = func(t *http.Transport) http.RoundTripper { return ntlmssp.Negotiator{t} }
	client, err := newwinrm.NewClientWithParameters(&newwinrm.Endpoint{Host: host,
		Port:     5986,
		HTTPS:    true,
		Insecure: true},
		username, password, params)
	if err != nil {
		log.Error("failed to create shell: ", err)
		return "", "", -1, err
	}

	stdout, stderr, exitcode, err := client.RunWithString(command, "")
	if err != nil {
		log.Error("failed to run cmd: ", err)
		return "", "", -1, err
	}
	log.Debug("stdout:", stdout, "stderr:", stderr, "exitcode:", exitcode)

	return stdout, stderr, exitcode, err
}
func (c *Communicator) Start(rc *packer.RemoteCmd) error {
	log.Printf("starting remote command: %s", rc.Command)

	// Create a new shell process on the guest
	params := winrm.DefaultParameters()
	params.Timeout = iso8601.FormatDuration(time.Hour * 24)
	client, err := winrm.NewClientWithParameters(c.endpoint, c.user, c.password, params)
	if err != nil {
		return err
	}

	shell, err := client.CreateShell()
	if err != nil {
		return err
	}

	cmd, err := shell.Execute(rc.Command)
	if err != nil {
		return err
	}

	go runCommand(shell, cmd, rc)
	return nil
}