Skip to content

Instantly share code, notes, and snippets.

@justdan96
Last active November 14, 2017 18:21
Show Gist options
  • Select an option

  • Save justdan96/075c25ee5bfdb0e46424e8ad2085ccc7 to your computer and use it in GitHub Desktop.

Select an option

Save justdan96/075c25ee5bfdb0e46424e8ad2085ccc7 to your computer and use it in GitHub Desktop.
patch for Terraform to add a new "Negotiate" parameter to the WinRM communicator, to allow NTLM authentication
diff --git communicator/winrm/communicator.go communicator/winrm/communicator.go
index c25c2bc63..78b528fb7 100644
--- communicator/winrm/communicator.go
+++ communicator/winrm/communicator.go
@@ -5,6 +5,7 @@ import (
"io"
"log"
"math/rand"
+ "net/http"
"strconv"
"strings"
"sync"
@@ -17,6 +18,8 @@ import (
// This import is a bit strange, but it's needed so `make updatedeps` can see and download it
_ "github.com/dylanmei/winrmtest"
+
+ ntlmssp "github.com/Azure/go-ntlmssp"
)
// Communicator represents the WinRM communicator
@@ -61,6 +64,14 @@ func (c *Communicator) Connect(o terraform.UIOutput) error {
params := winrm.DefaultParameters()
params.Timeout = formatDuration(c.Timeout())
+ // enable negotiate if the parameter is set
+ if c.connInfo.Negotiate {
+ params.TransportDecorator = func(transport *http.Transport) http.RoundTripper {
+ return &ntlmssp.Negotiator{
+ RoundTripper: transport,
+ }
+ }
+ }
client, err := winrm.NewClientWithParameters(
c.endpoint, c.connInfo.User, c.connInfo.Password, params)
if err != nil {
@@ -76,7 +87,8 @@ func (c *Communicator) Connect(o terraform.UIOutput) error {
" Password: %t\n"+
" HTTPS: %t\n"+
" Insecure: %t\n"+
- " CACert: %t",
+ " CACert: %t\n",
+ " Negotiate: %t",
c.connInfo.Host,
c.connInfo.Port,
c.connInfo.User,
@@ -84,6 +96,7 @@ func (c *Communicator) Connect(o terraform.UIOutput) error {
c.connInfo.HTTPS,
c.connInfo.Insecure,
c.connInfo.CACert != nil,
+ c.connInfo.Negotiate,
))
}
diff --git communicator/winrm/provisioner.go communicator/winrm/provisioner.go
index 2dab1e97d..d8a1a917b 100644
--- communicator/winrm/provisioner.go
+++ communicator/winrm/provisioner.go
@@ -41,6 +41,7 @@ type connectionInfo struct {
Timeout string
ScriptPath string `mapstructure:"script_path"`
TimeoutVal time.Duration `mapstructure:"-"`
+ Negotiate bool
}
// parseConnectionInfo is used to convert the ConnInfo of the InstanceState into
diff --git communicator/winrm/provisioner_test.go communicator/winrm/provisioner_test.go
index 9ed6f095d..c4d0653e0 100644
--- communicator/winrm/provisioner_test.go
+++ communicator/winrm/provisioner_test.go
@@ -10,13 +10,14 @@ func TestProvisioner_connInfo(t *testing.T) {
r := &terraform.InstanceState{
Ephemeral: terraform.EphemeralState{
ConnInfo: map[string]string{
- "type": "winrm",
- "user": "Administrator",
- "password": "supersecret",
- "host": "127.0.0.1",
- "port": "5985",
- "https": "true",
- "timeout": "30s",
+ "type": "winrm",
+ "user": "Administrator",
+ "password": "supersecret",
+ "host": "127.0.0.1",
+ "port": "5985",
+ "https": "true",
+ "timeout": "30s",
+ "negotiate": "false",
},
},
}
@@ -47,6 +48,9 @@ func TestProvisioner_connInfo(t *testing.T) {
if conf.ScriptPath != DefaultScriptPath {
t.Fatalf("expected: %v: got: %v", DefaultScriptPath, conf)
}
+ if conf.Negotiate != false {
+ t.Fatalf("expected: %v: got: %v", true, conf)
+ }
}
func TestProvisioner_connInfoIpv6(t *testing.T) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment