Merge pull request #5818 from mitchellh/issue-5790-password-in-cleartext
provisioner/shell: remove plaintext auth from Windows powershell
This commit is contained in:
commit
bd0626672b
|
@ -134,12 +134,7 @@ module VagrantPlugins
|
||||||
}.merge(opts || {})
|
}.merge(opts || {})
|
||||||
|
|
||||||
opts[:good_exit] = Array(opts[:good_exit])
|
opts[:good_exit] = Array(opts[:good_exit])
|
||||||
|
command = wrap_in_scheduled_task(command) if opts[:elevated]
|
||||||
if opts[:elevated]
|
|
||||||
guest_script_path = create_elevated_shell_script(command)
|
|
||||||
command = "powershell -executionpolicy bypass -file #{guest_script_path}"
|
|
||||||
end
|
|
||||||
|
|
||||||
output = shell.send(opts[:shell], command, &block)
|
output = shell.send(opts[:shell], command, &block)
|
||||||
execution_output(output, opts)
|
execution_output(output, opts)
|
||||||
end
|
end
|
||||||
|
@ -187,19 +182,15 @@ module VagrantPlugins
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates and uploads a PowerShell script which wraps the specified
|
# Creates and uploads a PowerShell script which wraps a command in a
|
||||||
# command in a scheduled task. The scheduled task allows commands to
|
# scheduled task. The scheduled task allows commands to run on the guest
|
||||||
# run on the guest as a true local admin without any of the restrictions
|
# as a true local admin without any of the restrictions that WinRM puts
|
||||||
# that WinRM puts in place.
|
# in place.
|
||||||
#
|
#
|
||||||
# @return The path to elevated_shell.ps1 on the guest
|
# @return The wrapper command to execute
|
||||||
def create_elevated_shell_script(command)
|
def wrap_in_scheduled_task(command)
|
||||||
path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__)
|
path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__)
|
||||||
script = Vagrant::Util::TemplateRenderer.render(path, options: {
|
script = Vagrant::Util::TemplateRenderer.render(path)
|
||||||
username: shell.username,
|
|
||||||
password: shell.password,
|
|
||||||
command: command.gsub("\"", "`\""),
|
|
||||||
})
|
|
||||||
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
|
guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1"
|
||||||
file = Tempfile.new(["vagrant-elevated-shell", "ps1"])
|
file = Tempfile.new(["vagrant-elevated-shell", "ps1"])
|
||||||
begin
|
begin
|
||||||
|
@ -211,7 +202,15 @@ module VagrantPlugins
|
||||||
file.close
|
file.close
|
||||||
file.unlink
|
file.unlink
|
||||||
end
|
end
|
||||||
guest_script_path
|
|
||||||
|
# convert to double byte unicode string then base64 encode
|
||||||
|
# just like PowerShell -EncodedCommand expects
|
||||||
|
wrapped_encoded_command = Base64.strict_encode64(
|
||||||
|
"#{command}; exit $LASTEXITCODE".encode('UTF-16LE', 'UTF-8'))
|
||||||
|
|
||||||
|
"powershell -executionpolicy bypass -file \"#{guest_script_path}\" " +
|
||||||
|
"-username \"#{shell.username}\" -password \"#{shell.password}\" " +
|
||||||
|
"-encoded_command \"#{wrapped_encoded_command}\""
|
||||||
end
|
end
|
||||||
|
|
||||||
# Handles the raw WinRM shell result and converts it to a
|
# Handles the raw WinRM shell result and converts it to a
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
$command = "<%= options[:command] %>" + '; exit $LASTEXITCODE'
|
param([String]$username, [String]$password, [String]$encoded_command)
|
||||||
$user = '<%= options[:username] %>'
|
|
||||||
$password = '<%= options[:password] %>'
|
|
||||||
|
|
||||||
$task_name = "WinRM_Elevated_Shell"
|
$task_name = "WinRM_Elevated_Shell"
|
||||||
$out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell.log"
|
$out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell.log"
|
||||||
|
@ -14,7 +12,7 @@ $task_xml = @'
|
||||||
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||||
<Principals>
|
<Principals>
|
||||||
<Principal id="Author">
|
<Principal id="Author">
|
||||||
<UserId>{user}</UserId>
|
<UserId>{username}</UserId>
|
||||||
<LogonType>Password</LogonType>
|
<LogonType>Password</LogonType>
|
||||||
<RunLevel>HighestAvailable</RunLevel>
|
<RunLevel>HighestAvailable</RunLevel>
|
||||||
</Principal>
|
</Principal>
|
||||||
|
@ -47,19 +45,17 @@ $task_xml = @'
|
||||||
</Task>
|
</Task>
|
||||||
'@
|
'@
|
||||||
|
|
||||||
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
|
|
||||||
$encoded_command = [Convert]::ToBase64String($bytes)
|
|
||||||
$arguments = "/c powershell.exe -EncodedCommand $encoded_command > $out_file 2>&1"
|
$arguments = "/c powershell.exe -EncodedCommand $encoded_command > $out_file 2>&1"
|
||||||
|
|
||||||
$task_xml = $task_xml.Replace("{arguments}", $arguments)
|
$task_xml = $task_xml.Replace("{arguments}", $arguments)
|
||||||
$task_xml = $task_xml.Replace("{user}", $user)
|
$task_xml = $task_xml.Replace("{username}", $username)
|
||||||
|
|
||||||
$schedule = New-Object -ComObject "Schedule.Service"
|
$schedule = New-Object -ComObject "Schedule.Service"
|
||||||
$schedule.Connect()
|
$schedule.Connect()
|
||||||
$task = $schedule.NewTask($null)
|
$task = $schedule.NewTask($null)
|
||||||
$task.XmlText = $task_xml
|
$task.XmlText = $task_xml
|
||||||
$folder = $schedule.GetFolder("\")
|
$folder = $schedule.GetFolder("\")
|
||||||
$folder.RegisterTaskDefinition($task_name, $task, 6, $user, $password, 1, $null) | Out-Null
|
$folder.RegisterTaskDefinition($task_name, $task, 6, $username, $password, 1, $null) | Out-Null
|
||||||
|
|
||||||
$registered_task = $folder.GetTask("\$task_name")
|
$registered_task = $folder.GetTask("\$task_name")
|
||||||
$registered_task.Run($null) | Out-Null
|
$registered_task.Run($null) | Out-Null
|
||||||
|
|
|
@ -55,7 +55,8 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do
|
||||||
it "wraps command in elevated shell script when elevated is true" do
|
it "wraps command in elevated shell script when elevated is true" do
|
||||||
expect(shell).to receive(:upload).with(kind_of(String), "c:/tmp/vagrant-elevated-shell.ps1")
|
expect(shell).to receive(:upload).with(kind_of(String), "c:/tmp/vagrant-elevated-shell.ps1")
|
||||||
expect(shell).to receive(:powershell) do |cmd|
|
expect(shell).to receive(:powershell) do |cmd|
|
||||||
expect(cmd).to eq("powershell -executionpolicy bypass -file c:/tmp/vagrant-elevated-shell.ps1")
|
expect(cmd).to eq("powershell -executionpolicy bypass -file \"c:/tmp/vagrant-elevated-shell.ps1\" " +
|
||||||
|
"-username \"vagrant\" -password \"password\" -encoded_command \"ZABpAHIAOwAgAGUAeABpAHQAIAAkAEwAQQBTAFQARQBYAEkAVABDAE8ARABFAA==\"")
|
||||||
end.and_return({ exitcode: 0 })
|
end.and_return({ exitcode: 0 })
|
||||||
expect(subject.execute("dir", { elevated: true })).to eq(0)
|
expect(subject.execute("dir", { elevated: true })).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue