1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
require 'spec_helper'
describe "Puppet::Util::Windows::Process", :if => Puppet::Util::Platform.windows? do
describe "as an admin" do
it "should have the SeCreateSymbolicLinkPrivilege necessary to create symlinks" do
# this is a bit of a lame duck test since it requires running user to be admin
# a better integration test would create a new user with the privilege and verify
expect(Puppet::Util::Windows::User).to be_admin
expect(Puppet::Util::Windows::Process.process_privilege_symlink?).to be_truthy
end
it "should be able to lookup a standard Windows process privilege" do
Puppet::Util::Windows::Process.lookup_privilege_value('SeShutdownPrivilege') do |luid|
expect(luid).not_to be_nil
expect(luid).to be_instance_of(Puppet::Util::Windows::Process::LUID)
end
end
it "should raise an error for an unknown privilege name" do
expect { Puppet::Util::Windows::Process.lookup_privilege_value('foo') }.to raise_error do |error|
expect(error).to be_a(Puppet::Util::Windows::Error)
expect(error.code).to eq(1313) # ERROR_NO_SUCH_PRIVILEGE
end
end
end
describe "when reading environment variables" do
it "will ignore only keys or values with corrupt byte sequences" do
env_vars = {}
# Create a UTF-16LE version of the below null separated environment string
# "a=b\x00c=d\x00e=\xDD\xDD\x00f=g\x00\x00"
env_var_block =
"a=b\x00".encode(Encoding::UTF_16LE) +
"c=d\x00".encode(Encoding::UTF_16LE) +
'e='.encode(Encoding::UTF_16LE) + "\xDD\xDD".force_encoding(Encoding::UTF_16LE) + "\x00".encode(Encoding::UTF_16LE) +
"f=g\x00\x00".encode(Encoding::UTF_16LE)
env_var_block_bytes = env_var_block.bytes.to_a
FFI::MemoryPointer.new(:byte, env_var_block_bytes.count) do |ptr|
# uchar here is synonymous with byte
ptr.put_array_of_uchar(0, env_var_block_bytes)
# stub the block of memory that the Win32 API would typically return via pointer
allow(Puppet::Util::Windows::Process).to receive(:GetEnvironmentStringsW).and_return(ptr)
# stub out the real API call to free memory, else process crashes
allow(Puppet::Util::Windows::Process).to receive(:FreeEnvironmentStringsW)
env_vars = Puppet::Util::Windows::Process.get_environment_strings
end
# based on corrupted memory, the e=\xDD\xDD should have been removed from the set
expect(env_vars).to eq({'a' => 'b', 'c' => 'd', 'f' => 'g'})
# and Puppet should emit a warning about it
expect(@logs.last.level).to eq(:warning)
expect(@logs.last.message).to eq("Discarding environment variable e=\uFFFD which contains invalid bytes")
end
end
describe "when setting environment variables" do
let(:name) { SecureRandom.uuid }
around :each do |example|
begin
example.run
ensure
Puppet::Util::Windows::Process.set_environment_variable(name, nil)
end
end
it "sets environment variables containing '='" do
value = 'foo=bar'
Puppet::Util::Windows::Process.set_environment_variable(name, value)
env = Puppet::Util::Windows::Process.get_environment_strings
expect(env[name]).to eq(value)
end
it "sets environment variables contains spaces" do
Puppet::Util::Windows::Process.set_environment_variable(name, '')
env = Puppet::Util::Windows::Process.get_environment_strings
expect(env[name]).to eq('')
end
it "sets environment variables containing UTF-8" do
rune_utf8 = "\u16A0\u16C7\u16BB\u16EB\u16D2\u16E6\u16A6\u16EB\u16A0\u16B1\u16A9\u16A0\u16A2\u16B1\u16EB\u16A0\u16C1\u16B1\u16AA\u16EB\u16B7\u16D6\u16BB\u16B9\u16E6\u16DA\u16B3\u16A2\u16D7"
Puppet::Util::Windows::Process.set_environment_variable(name, rune_utf8)
env = Puppet::Util::Windows::Process.get_environment_strings
expect(env[name]).to eq(rune_utf8)
end
end
end
|