winrm 2.2.3 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/bin/rwinrm +90 -97
- data/lib/winrm/connection.rb +84 -86
- data/lib/winrm/connection_opts.rb +90 -91
- data/lib/winrm/exceptions.rb +14 -2
- data/lib/winrm/http/response_handler.rb +127 -96
- data/lib/winrm/http/transport.rb +462 -427
- data/lib/winrm/http/transport_factory.rb +1 -5
- data/lib/winrm/output.rb +1 -2
- data/lib/winrm/psrp/fragment.rb +0 -2
- data/lib/winrm/psrp/message.rb +128 -130
- data/lib/winrm/psrp/message_data/base.rb +0 -2
- data/lib/winrm/psrp/message_data/error_record.rb +2 -2
- data/lib/winrm/psrp/message_data/pipeline_host_call.rb +0 -2
- data/lib/winrm/psrp/message_data/pipeline_output.rb +48 -54
- data/lib/winrm/psrp/message_data/pipeline_state.rb +0 -2
- data/lib/winrm/psrp/message_data/runspacepool_host_call.rb +0 -2
- data/lib/winrm/psrp/message_data/runspacepool_state.rb +0 -2
- data/lib/winrm/psrp/message_data/session_capability.rb +0 -2
- data/lib/winrm/psrp/message_data.rb +0 -2
- data/lib/winrm/psrp/message_defragmenter.rb +2 -2
- data/lib/winrm/psrp/message_factory.rb +16 -5
- data/lib/winrm/psrp/message_fragmenter.rb +1 -3
- data/lib/winrm/psrp/powershell_output_decoder.rb +142 -144
- data/lib/winrm/psrp/receive_response_reader.rb +3 -5
- data/lib/winrm/psrp/uuid.rb +1 -2
- data/lib/winrm/shells/base.rb +7 -4
- data/lib/winrm/shells/cmd.rb +63 -65
- data/lib/winrm/shells/power_shell.rb +207 -202
- data/lib/winrm/shells/retryable.rb +44 -45
- data/lib/winrm/shells/shell_factory.rb +0 -2
- data/lib/winrm/version.rb +1 -3
- data/lib/winrm/wsmv/base.rb +0 -2
- data/lib/winrm/wsmv/cleanup_command.rb +1 -2
- data/lib/winrm/wsmv/close_shell.rb +1 -2
- data/lib/winrm/wsmv/command.rb +2 -3
- data/lib/winrm/wsmv/command_output.rb +2 -3
- data/lib/winrm/wsmv/command_output_decoder.rb +1 -2
- data/lib/winrm/wsmv/configuration.rb +0 -2
- data/lib/winrm/wsmv/create_pipeline.rb +0 -2
- data/lib/winrm/wsmv/create_shell.rb +2 -6
- data/lib/winrm/wsmv/header.rb +213 -215
- data/lib/winrm/wsmv/init_runspace_pool.rb +96 -95
- data/lib/winrm/wsmv/iso8601_duration.rb +0 -2
- data/lib/winrm/wsmv/keep_alive.rb +0 -2
- data/lib/winrm/wsmv/receive_response_reader.rb +128 -126
- data/lib/winrm/wsmv/send_data.rb +0 -2
- data/lib/winrm/wsmv/soap.rb +0 -2
- data/lib/winrm/wsmv/wql_pull.rb +54 -56
- data/lib/winrm/wsmv/wql_query.rb +98 -99
- data/lib/winrm/wsmv/write_stdin.rb +0 -2
- data/lib/winrm.rb +3 -5
- metadata +81 -135
- data/.gitignore +0 -10
- data/.rubocop.yml +0 -26
- data/.travis.yml +0 -11
- data/Gemfile +0 -3
- data/Rakefile +0 -34
- data/Vagrantfile +0 -6
- data/WinrmAppveyor.psm1 +0 -32
- data/appveyor.yml +0 -51
- data/changelog.md +0 -128
- data/preamble +0 -17
- data/tests/integration/auth_timeout_spec.rb +0 -18
- data/tests/integration/cmd_spec.rb +0 -131
- data/tests/integration/config-example.yml +0 -16
- data/tests/integration/issue_59_spec.rb +0 -26
- data/tests/integration/powershell_spec.rb +0 -165
- data/tests/integration/spec_helper.rb +0 -65
- data/tests/integration/transport_spec.rb +0 -99
- data/tests/integration/wql_spec.rb +0 -34
- data/tests/matchers.rb +0 -60
- data/tests/spec/configuration_spec.rb +0 -184
- data/tests/spec/connection_spec.rb +0 -39
- data/tests/spec/exception_spec.rb +0 -50
- data/tests/spec/http/transport_factory_spec.rb +0 -68
- data/tests/spec/http/transport_spec.rb +0 -44
- data/tests/spec/output_spec.rb +0 -127
- data/tests/spec/psrp/fragment_spec.rb +0 -62
- data/tests/spec/psrp/message_data/base_spec.rb +0 -13
- data/tests/spec/psrp/message_data/error_record_spec.rb +0 -41
- data/tests/spec/psrp/message_data/pipeline_host_call_spec.rb +0 -25
- data/tests/spec/psrp/message_data/pipeline_output_spec.rb +0 -32
- data/tests/spec/psrp/message_data/pipeline_state_spec.rb +0 -40
- data/tests/spec/psrp/message_data/runspace_pool_host_call_spec.rb +0 -25
- data/tests/spec/psrp/message_data/runspacepool_state_spec.rb +0 -16
- data/tests/spec/psrp/message_data/session_capability_spec.rb +0 -30
- data/tests/spec/psrp/message_data_spec.rb +0 -35
- data/tests/spec/psrp/message_defragmenter_spec.rb +0 -47
- data/tests/spec/psrp/message_fragmenter_spec.rb +0 -105
- data/tests/spec/psrp/powershell_output_decoder_spec.rb +0 -100
- data/tests/spec/psrp/psrp_message_spec.rb +0 -70
- data/tests/spec/psrp/recieve_response_reader_spec.rb +0 -172
- data/tests/spec/psrp/uuid_spec.rb +0 -28
- data/tests/spec/response_handler_spec.rb +0 -61
- data/tests/spec/shells/base_spec.rb +0 -225
- data/tests/spec/shells/cmd_spec.rb +0 -75
- data/tests/spec/shells/powershell_spec.rb +0 -175
- data/tests/spec/spec_helper.rb +0 -47
- data/tests/spec/stubs/clixml/error_record.xml.erb +0 -84
- data/tests/spec/stubs/clixml/pipeline_state.xml.erb +0 -88
- data/tests/spec/stubs/responses/get_command_output_response.xml.erb +0 -13
- data/tests/spec/stubs/responses/get_command_output_response_not_done.xml.erb +0 -10
- data/tests/spec/stubs/responses/get_powershell_keepalive_response.xml.erb +0 -10
- data/tests/spec/stubs/responses/get_powershell_output_response.xml.erb +0 -12
- data/tests/spec/stubs/responses/get_powershell_output_response_not_done.xml.erb +0 -9
- data/tests/spec/stubs/responses/open_shell_v1.xml +0 -19
- data/tests/spec/stubs/responses/open_shell_v2.xml +0 -20
- data/tests/spec/stubs/responses/soap_fault_v1.xml +0 -36
- data/tests/spec/stubs/responses/soap_fault_v2.xml +0 -42
- data/tests/spec/stubs/responses/wmi_error_v2.xml +0 -41
- data/tests/spec/wsmv/cleanup_command_spec.rb +0 -22
- data/tests/spec/wsmv/close_shell_spec.rb +0 -17
- data/tests/spec/wsmv/command_output_decoder_spec.rb +0 -37
- data/tests/spec/wsmv/command_output_spec.rb +0 -45
- data/tests/spec/wsmv/command_spec.rb +0 -19
- data/tests/spec/wsmv/configuration_spec.rb +0 -17
- data/tests/spec/wsmv/create_pipeline_spec.rb +0 -31
- data/tests/spec/wsmv/create_shell_spec.rb +0 -38
- data/tests/spec/wsmv/init_runspace_pool_spec.rb +0 -36
- data/tests/spec/wsmv/keep_alive_spec.rb +0 -21
- data/tests/spec/wsmv/receive_response_reader_spec.rb +0 -123
- data/tests/spec/wsmv/send_data_spec.rb +0 -30
- data/tests/spec/wsmv/wql_query_spec.rb +0 -13
- data/tests/spec/wsmv/write_stdin_spec.rb +0 -22
- data/winrm.gemspec +0 -47
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message_data/base'
|
|
4
|
-
require 'winrm/psrp/message_data/pipeline_state'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageData::PipelineState do
|
|
7
|
-
let(:test_data_xml_template) do
|
|
8
|
-
ERB.new(stubbed_clixml('pipeline_state.xml.erb'))
|
|
9
|
-
end
|
|
10
|
-
let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::FAILED }
|
|
11
|
-
let(:error_message) { 'an error occured' }
|
|
12
|
-
let(:category_message) { 'category message' }
|
|
13
|
-
let(:error_id) { 'an error occured' }
|
|
14
|
-
let(:raw_data) { test_data_xml_template.result(binding) }
|
|
15
|
-
subject { described_class.new(raw_data) }
|
|
16
|
-
|
|
17
|
-
it 'returns the state' do
|
|
18
|
-
expect(subject.pipeline_state).to eq(pipeline_state)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it 'returns the exception' do
|
|
22
|
-
expect(subject.exception_as_error_record.exception[:message]).to eq(error_message)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'returns the FullyQualifiedErrorId' do
|
|
26
|
-
expect(subject.exception_as_error_record.fully_qualified_error_id).to eq(error_id)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'returns the error category message' do
|
|
30
|
-
expect(subject.exception_as_error_record.error_category_message).to eq(category_message)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
context 'state is not failed' do
|
|
34
|
-
let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::COMPLETED }
|
|
35
|
-
|
|
36
|
-
it 'has a nil exception' do
|
|
37
|
-
expect(subject.exception_as_error_record).to be(nil)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message_data/base'
|
|
4
|
-
require 'winrm/psrp/message_data/runspacepool_host_call'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageData::RunspacepoolHostCall do
|
|
7
|
-
let(:raw_data) do
|
|
8
|
-
"\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I64 N=\"ci\">-100</I64><Obj N=\"mi\" RefId=\"1\">"\
|
|
9
|
-
'<TN RefId="0"><T>System.Management.Automation.Remoting.RemoteHostMethodId</T>'\
|
|
10
|
-
'<T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN>'\
|
|
11
|
-
'<ToString>WriteLine3</ToString><I32>17</I32></Obj><Obj N="mp" RefId="2">'\
|
|
12
|
-
'<TN RefId="1"><T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST>'\
|
|
13
|
-
'<I32>7</I32><I32>0</I32><S>hello</S></LST></Obj></MS></Obj>'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
subject { described_class.new(raw_data) }
|
|
17
|
-
|
|
18
|
-
it 'parses method identifier' do
|
|
19
|
-
expect(subject.method_identifier).to eq('WriteLine3')
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'parses method parameters' do
|
|
23
|
-
expect(subject.method_parameters[:s]).to eq('hello')
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message_data/base'
|
|
4
|
-
require 'winrm/psrp/message_data/runspacepool_state'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageData::RunspacepoolState do
|
|
7
|
-
let(:raw_data) do
|
|
8
|
-
"\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I32 N=\"RunspaceState\">2</I32></MS></Obj>"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
subject { described_class.new(raw_data) }
|
|
12
|
-
|
|
13
|
-
it 'parses runspace state' do
|
|
14
|
-
expect(subject.runspace_state).to eq(WinRM::PSRP::MessageData::RunspacepoolState::OPENED)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message_data/base'
|
|
4
|
-
require 'winrm/psrp/message_data/session_capability'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageData::SessionCapability do
|
|
7
|
-
let(:protocol_version) { '2.2' }
|
|
8
|
-
let(:ps_version) { '2.0' }
|
|
9
|
-
let(:serialization_version) { '1.1.0.1' }
|
|
10
|
-
let(:raw_data) do
|
|
11
|
-
"\xEF\xBB\xBF<Obj RefId=\"0\"><MS>"\
|
|
12
|
-
"<Version N=\"protocolversion\">#{protocol_version}</Version>"\
|
|
13
|
-
"<Version N=\"PSVersion\">#{ps_version}</Version>"\
|
|
14
|
-
"<Version N=\"SerializationVersion\">#{serialization_version}</Version></MS></Obj>"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
subject { described_class.new(raw_data) }
|
|
18
|
-
|
|
19
|
-
it 'parses protocol version' do
|
|
20
|
-
expect(subject.protocol_version).to eq(protocol_version)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'parses ps version' do
|
|
24
|
-
expect(subject.ps_version).to eq(ps_version)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'parses serialization version' do
|
|
28
|
-
expect(subject.serialization_version).to eq(serialization_version)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message'
|
|
4
|
-
require 'winrm/psrp/message_data'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageData do
|
|
7
|
-
describe '#parse' do
|
|
8
|
-
let(:raw_data) { 'raw_data' }
|
|
9
|
-
let(:message) do
|
|
10
|
-
WinRM::PSRP::Message.new(
|
|
11
|
-
'00000000-0000-0000-0000-000000000000',
|
|
12
|
-
message_type,
|
|
13
|
-
raw_data
|
|
14
|
-
)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
subject { WinRM::PSRP::MessageData.parse(message) }
|
|
18
|
-
|
|
19
|
-
context 'defined message type' do
|
|
20
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
21
|
-
|
|
22
|
-
it 'creates correct message data type' do
|
|
23
|
-
expect(subject).to be_a(WinRM::PSRP::MessageData::PipelineOutput)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
context 'undefined message type' do
|
|
28
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_input] }
|
|
29
|
-
|
|
30
|
-
it 'returns nill' do
|
|
31
|
-
expect(subject).to be nil
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message_defragmenter'
|
|
4
|
-
|
|
5
|
-
describe WinRM::PSRP::MessageDefragmenter do
|
|
6
|
-
context 'a real life fragment' do
|
|
7
|
-
let(:bytes) do
|
|
8
|
-
"\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00I\x01"\
|
|
9
|
-
"\x00\x00\x00\x04\x10\x04\x00Kk/=Z\xD3-E\x81v\xA0+6\xB1\xD3\x88\n\xED\x90\x9Cj\xE7PG"\
|
|
10
|
-
"\x9F\xA2\xB2\xC99to9\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string
|
|
11
|
-
end
|
|
12
|
-
subject { described_class.new.defragment(Base64.encode64(bytes)) }
|
|
13
|
-
|
|
14
|
-
it 'parses the data' do
|
|
15
|
-
expect(subject.data).to eq("\xEF\xBB\xBF<S>some data_x000D__x000A_</S>".to_byte_string)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'parses the destination' do
|
|
19
|
-
expect(subject.destination).to eq(1)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'parses the message type' do
|
|
23
|
-
expect(subject.type).to eq(WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output])
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
context 'multiple fragments' do
|
|
28
|
-
let(:blob) do
|
|
29
|
-
WinRM::PSRP::Message.new(
|
|
30
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
31
|
-
WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
|
|
32
|
-
'This is a fragmented message'
|
|
33
|
-
)
|
|
34
|
-
end
|
|
35
|
-
let(:fragment1) { WinRM::PSRP::Fragment.new(1, blob.bytes[0..5], 0, true, false) }
|
|
36
|
-
let(:fragment2) { WinRM::PSRP::Fragment.new(1, blob.bytes[6..10], 1, false, false) }
|
|
37
|
-
let(:fragment3) { WinRM::PSRP::Fragment.new(1, blob.bytes[11..-1], 2, false, true) }
|
|
38
|
-
|
|
39
|
-
it 'pieces the message together' do
|
|
40
|
-
subject.defragment(Base64.strict_encode64(fragment1.bytes.pack('C*')))
|
|
41
|
-
subject.defragment(Base64.strict_encode64(fragment2.bytes.pack('C*')))
|
|
42
|
-
message = subject.defragment(Base64.strict_encode64(fragment3.bytes.pack('C*')))
|
|
43
|
-
|
|
44
|
-
expect(message.data[3..-1]).to eq(blob.data)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message'
|
|
4
|
-
require 'winrm/psrp/message_fragmenter'
|
|
5
|
-
|
|
6
|
-
describe WinRM::PSRP::MessageFragmenter do
|
|
7
|
-
let(:message) do
|
|
8
|
-
WinRM::PSRP::Message.new(
|
|
9
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
10
|
-
WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
|
|
11
|
-
data
|
|
12
|
-
)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
subject do
|
|
16
|
-
fragmenter = described_class.new(45)
|
|
17
|
-
fragments = []
|
|
18
|
-
fragmenter.fragment(message) do |fragment|
|
|
19
|
-
fragments.push(fragment)
|
|
20
|
-
end
|
|
21
|
-
fragments
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context 'one fragment' do
|
|
25
|
-
let(:data) { 'th' }
|
|
26
|
-
|
|
27
|
-
it 'returns 1 fragment' do
|
|
28
|
-
expect(subject.length).to eq(1)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it 'has blob data equal to the message bytes' do
|
|
32
|
-
expect(subject[0].blob.length).to eq(message.bytes.length)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'identifies the fragment as start and end' do
|
|
36
|
-
expect(subject[0].start_fragment).to eq(true)
|
|
37
|
-
expect(subject[0].end_fragment).to eq(true)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it 'assigns fragment id correctly' do
|
|
41
|
-
expect(subject[0].fragment_id).to eq(0)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
context 'two fragments' do
|
|
46
|
-
let(:data) { 'This is a fragmented message' }
|
|
47
|
-
|
|
48
|
-
it 'splits the message' do
|
|
49
|
-
expect(subject.length).to eq(2)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it 'has a sum of blob data equal to the message bytes' do
|
|
53
|
-
expect(subject[0].blob.length + subject[1].blob.length).to eq(message.bytes.length)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'identifies the first fragment as start and not end' do
|
|
57
|
-
expect(subject[0].start_fragment).to eq(true)
|
|
58
|
-
expect(subject[0].end_fragment).to eq(false)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'identifies the first fragment as start and not end' do
|
|
62
|
-
expect(subject[1].start_fragment).to eq(false)
|
|
63
|
-
expect(subject[1].end_fragment).to eq(true)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'assigns incementing fragment ids' do
|
|
67
|
-
expect(subject[0].fragment_id).to eq(0)
|
|
68
|
-
expect(subject[1].fragment_id).to eq(1)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
context 'three fragments' do
|
|
73
|
-
let(:data) { 'This is a fragmented message because framents are lovely' }
|
|
74
|
-
|
|
75
|
-
it 'splits the message' do
|
|
76
|
-
expect(subject.length).to eq(3)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it 'has a sum of blob data equal to the message bytes' do
|
|
80
|
-
expect(subject[0].blob.length + subject[1].blob.length + subject[2].blob.length)
|
|
81
|
-
.to eq(message.bytes.length)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it 'identifies the first fragment as start and not end' do
|
|
85
|
-
expect(subject[0].start_fragment).to eq(true)
|
|
86
|
-
expect(subject[0].end_fragment).to eq(false)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it 'identifies the first fragment as start and not end' do
|
|
90
|
-
expect(subject[1].start_fragment).to eq(false)
|
|
91
|
-
expect(subject[1].end_fragment).to eq(false)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
it 'identifies the third fragment as not start and end' do
|
|
95
|
-
expect(subject[2].start_fragment).to eq(false)
|
|
96
|
-
expect(subject[2].end_fragment).to eq(true)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it 'assigns incementing fragment ids' do
|
|
100
|
-
expect(subject[0].fragment_id).to eq(0)
|
|
101
|
-
expect(subject[1].fragment_id).to eq(1)
|
|
102
|
-
expect(subject[2].fragment_id).to eq(2)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/powershell_output_decoder'
|
|
4
|
-
|
|
5
|
-
describe WinRM::PSRP::PowershellOutputDecoder do
|
|
6
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:error_record] }
|
|
7
|
-
let(:data) { 'blah' }
|
|
8
|
-
let(:message) do
|
|
9
|
-
WinRM::PSRP::Message.new(
|
|
10
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
11
|
-
message_type,
|
|
12
|
-
data,
|
|
13
|
-
'4218a578-0f18-4b19-82c3-46b433319126'
|
|
14
|
-
)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
subject { described_class.new.decode(message) }
|
|
18
|
-
|
|
19
|
-
context 'undecodable message type' do
|
|
20
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:public_key] }
|
|
21
|
-
|
|
22
|
-
it 'ignores message' do
|
|
23
|
-
expect(subject).to be nil
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
context 'undecodable method identifier' do
|
|
28
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_host_call] }
|
|
29
|
-
let(:data) do
|
|
30
|
-
"\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I64 N=\"ci\">-100</I64><Obj N=\"mi\" RefId=\"1\">"\
|
|
31
|
-
'<TN RefId="0"><T>System.Management.Automation.Remoting.RemoteHostMethodId</T>'\
|
|
32
|
-
'<T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN>'\
|
|
33
|
-
'<ToString>WriteProgress</ToString><I32>17</I32></Obj><Obj N="mp" RefId="2">'\
|
|
34
|
-
'<TN RefId="1"><T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST>'\
|
|
35
|
-
'<I32>7</I32><I32>0</I32><S>some_x000D__x000A_data</S></LST></Obj></MS></Obj>'
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it 'ignores message' do
|
|
39
|
-
expect(subject).to be nil
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
context 'receiving pipeline output' do
|
|
44
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
45
|
-
let(:data) { '<obj><S>some data</S></obj>' }
|
|
46
|
-
|
|
47
|
-
it 'decodes output' do
|
|
48
|
-
expect(subject).to eq("some data\r\n")
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context 'writeline with new line in middle' do
|
|
53
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_host_call] }
|
|
54
|
-
let(:data) do
|
|
55
|
-
"\xEF\xBB\xBF<Obj RefId=\"0\"><MS><I64 N=\"ci\">-100</I64><Obj N=\"mi\" RefId=\"1\">"\
|
|
56
|
-
'<TN RefId="0"><T>System.Management.Automation.Remoting.RemoteHostMethodId</T>'\
|
|
57
|
-
'<T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN>'\
|
|
58
|
-
'<ToString>WriteLine3</ToString><I32>17</I32></Obj><Obj N="mp" RefId="2">'\
|
|
59
|
-
'<TN RefId="1"><T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST>'\
|
|
60
|
-
'<I32>7</I32><I32>0</I32><S>some_x000D__x000A_data</S></LST></Obj></MS></Obj>'
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it 'decodes and replaces newline' do
|
|
64
|
-
expect(subject).to eq("some\r\ndata\r\n")
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
context 'receiving error record' do
|
|
69
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:error_record] }
|
|
70
|
-
let(:test_data_error_xml_template) do
|
|
71
|
-
ERB.new(stubbed_clixml('error_record.xml.erb'))
|
|
72
|
-
end
|
|
73
|
-
let(:error_message) { 'an error' }
|
|
74
|
-
let(:script_root) { 'script_root' }
|
|
75
|
-
let(:category_message) { 'category message' }
|
|
76
|
-
let(:stack_trace) { 'stack trace' }
|
|
77
|
-
let(:error_id) { 'Microsoft.PowerShell.Commands.WriteErrorException' }
|
|
78
|
-
let(:data) { test_data_error_xml_template.result(binding) }
|
|
79
|
-
|
|
80
|
-
it 'decodes error record' do
|
|
81
|
-
expect(subject).to match(/#{error_message}/)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
context 'receiving error record in pipeline state' do
|
|
86
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_state] }
|
|
87
|
-
let(:test_data_error_xml_template) do
|
|
88
|
-
ERB.new(stubbed_clixml('pipeline_state.xml.erb'))
|
|
89
|
-
end
|
|
90
|
-
let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::FAILED }
|
|
91
|
-
let(:error_message) { 'an error' }
|
|
92
|
-
let(:category_message) { 'category message' }
|
|
93
|
-
let(:error_id) { 'an error' }
|
|
94
|
-
let(:data) { test_data_error_xml_template.result(binding) }
|
|
95
|
-
|
|
96
|
-
it 'decodes error record' do
|
|
97
|
-
expect(subject).to match(/#{error_message}/)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/message'
|
|
4
|
-
|
|
5
|
-
describe WinRM::PSRP::Message do
|
|
6
|
-
context 'all fields provided' do
|
|
7
|
-
let(:payload) { 'this is my payload' }
|
|
8
|
-
subject do
|
|
9
|
-
described_class.new(
|
|
10
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
11
|
-
WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output],
|
|
12
|
-
payload,
|
|
13
|
-
'4218a578-0f18-4b19-82c3-46b433319126')
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'sets the destination to server LE' do
|
|
17
|
-
expect(subject.bytes[0..3]).to eq([2, 0, 0, 0])
|
|
18
|
-
end
|
|
19
|
-
it 'sets the message type LE' do
|
|
20
|
-
expect(subject.bytes[4..7]).to eq([4, 16, 4, 0])
|
|
21
|
-
end
|
|
22
|
-
it 'sets the runspace pool id' do
|
|
23
|
-
expect(subject.bytes[8..23]).to eq(
|
|
24
|
-
[186, 251, 27, 188, 21, 130, 4, 74, 178, 223, 122, 58, 192, 49, 14, 22])
|
|
25
|
-
end
|
|
26
|
-
it 'sets the pipeline id' do
|
|
27
|
-
expect(subject.bytes[24..39]).to eq(
|
|
28
|
-
[120, 165, 24, 66, 24, 15, 25, 75, 130, 195, 70, 180, 51, 49, 145, 38])
|
|
29
|
-
end
|
|
30
|
-
it 'prefixes the blob with BOM' do
|
|
31
|
-
expect(subject.bytes[40..42]).to eq([239, 187, 191])
|
|
32
|
-
end
|
|
33
|
-
it 'contains at least the first 8 bytes of the XML payload' do
|
|
34
|
-
expect(subject.bytes[43..-1]).to eq(payload.bytes)
|
|
35
|
-
end
|
|
36
|
-
it 'parses the data' do
|
|
37
|
-
expect(subject.parsed_data).to be_a(WinRM::PSRP::MessageData::PipelineOutput)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
context 'create' do
|
|
42
|
-
it 'raises error when message type is not valid' do
|
|
43
|
-
expect do
|
|
44
|
-
WinRM::PSRP::Message.new(
|
|
45
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
46
|
-
0x00000000,
|
|
47
|
-
%(<Obj RefId="0"/>),
|
|
48
|
-
'4218a578-0f18-4b19-82c3-46b433319126')
|
|
49
|
-
end.to raise_error(RuntimeError)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context 'no command id' do
|
|
54
|
-
subject(:msg) do
|
|
55
|
-
payload = <<-HERE.unindent
|
|
56
|
-
<Obj RefId="0"><MS><Version N="protocolversion">2.3</Version>
|
|
57
|
-
<Version N="PSVersion">2.0</Version><Version N="SerializationVersion">1.1.0.1</Version></MS>
|
|
58
|
-
</Obj>
|
|
59
|
-
HERE
|
|
60
|
-
WinRM::PSRP::Message.new(
|
|
61
|
-
'bc1bfbba-8215-4a04-b2df-7a3ac0310e16',
|
|
62
|
-
WinRM::PSRP::Message::MESSAGE_TYPES[:session_capability],
|
|
63
|
-
payload)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
it 'sets the pipeline id to empty' do
|
|
67
|
-
expect(msg.bytes[24..39]).to eq([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
require 'winrm/psrp/receive_response_reader'
|
|
4
|
-
|
|
5
|
-
describe WinRM::PSRP::ReceiveResponseReader do
|
|
6
|
-
let(:shell_id) { 'F4A2622B-B842-4EB8-8A78-0225C8A993DF' }
|
|
7
|
-
let(:command_id) { 'A2A2622B-B842-4EB8-8A78-0225C8A993DF' }
|
|
8
|
-
let(:output_message) { double('output_message', build: 'output_message') }
|
|
9
|
-
let(:test_data_xml_template) do
|
|
10
|
-
ERB.new(stubbed_response('get_powershell_output_response.xml.erb'))
|
|
11
|
-
end
|
|
12
|
-
let(:test_data_xml_template_not_done) do
|
|
13
|
-
ERB.new(stubbed_response('get_powershell_output_response_not_done.xml.erb'))
|
|
14
|
-
end
|
|
15
|
-
let(:test_data_text) { 'some data' }
|
|
16
|
-
let(:test_data) { "<obj><S>#{test_data_text}</S></obj>" }
|
|
17
|
-
let(:message) do
|
|
18
|
-
WinRM::PSRP::Message.new(
|
|
19
|
-
shell_id,
|
|
20
|
-
message_type,
|
|
21
|
-
test_data,
|
|
22
|
-
command_id
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
let(:fragment) { WinRM::PSRP::Fragment.new(1, message.bytes) }
|
|
26
|
-
let(:test_data_stdout) { Base64.strict_encode64(fragment.bytes.pack('C*')) }
|
|
27
|
-
let(:transport) { {} }
|
|
28
|
-
|
|
29
|
-
before do
|
|
30
|
-
allow(transport).to receive(:send_request).and_return(
|
|
31
|
-
REXML::Document.new(test_data_xml_template.result(binding))
|
|
32
|
-
)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
subject do
|
|
36
|
-
described_class.new(
|
|
37
|
-
transport,
|
|
38
|
-
Logging.logger['test']
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
describe '#read_output' do
|
|
43
|
-
context 'response doc stdout with pipeline output' do
|
|
44
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
45
|
-
|
|
46
|
-
it 'outputs to stdout' do
|
|
47
|
-
expect(
|
|
48
|
-
subject.read_output(output_message).stdout
|
|
49
|
-
).to eq("#{test_data_text}\r\n")
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context 'response doc stdout error record' do
|
|
54
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:error_record] }
|
|
55
|
-
let(:test_data_error_xml_template) do
|
|
56
|
-
ERB.new(stubbed_clixml('error_record.xml.erb'))
|
|
57
|
-
end
|
|
58
|
-
let(:error_message) { 'an error' }
|
|
59
|
-
let(:script_root) { 'script_root' }
|
|
60
|
-
let(:category_message) { 'category message' }
|
|
61
|
-
let(:stack_trace) { 'stack trace' }
|
|
62
|
-
let(:error_id) { 'Microsoft.PowerShell.Commands.WriteErrorException' }
|
|
63
|
-
let(:test_data) { test_data_error_xml_template.result(binding) }
|
|
64
|
-
|
|
65
|
-
it 'outputs to stderr' do
|
|
66
|
-
expect(
|
|
67
|
-
subject.read_output(output_message).stderr
|
|
68
|
-
).to match(/#{error_message}/)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
context 'response doc failed pipeline state' do
|
|
73
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_state] }
|
|
74
|
-
let(:test_data_error_xml_template) do
|
|
75
|
-
ERB.new(stubbed_clixml('pipeline_state.xml.erb'))
|
|
76
|
-
end
|
|
77
|
-
let(:pipeline_state) { WinRM::PSRP::MessageData::PipelineState::FAILED }
|
|
78
|
-
let(:error_message) { 'an error' }
|
|
79
|
-
let(:category_message) { 'category message' }
|
|
80
|
-
let(:error_id) { 'Microsoft.PowerShell.Commands.WriteErrorException' }
|
|
81
|
-
let(:test_data) { test_data_error_xml_template.result(binding) }
|
|
82
|
-
|
|
83
|
-
it 'outputs to stderr' do
|
|
84
|
-
expect(
|
|
85
|
-
subject.read_output(output_message).stderr
|
|
86
|
-
).to match(/#{error_message}/)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context 'response doc writing error to host' do
|
|
91
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_host_call] }
|
|
92
|
-
let(:test_data) do
|
|
93
|
-
"<Obj RefId='0'><MS><I64 N='ci'>-100</I64><Obj N='mi' RefId='1'><TN RefId='0'>" \
|
|
94
|
-
'<T>System.Management.Automation.Remoting.RemoteHostMethodId</T><T>System.Enum</T>' \
|
|
95
|
-
'<T>System.ValueType</T><T>System.Object</T></TN><ToString>WriteErrorLine</ToString>' \
|
|
96
|
-
"<I32>18</I32></Obj><Obj N='mp' RefId='2'><TN RefId='1'>" \
|
|
97
|
-
'<T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST><S>errors</S></LST>' \
|
|
98
|
-
'</Obj></MS></Obj>'
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'outputs to stderr' do
|
|
102
|
-
expect(
|
|
103
|
-
subject.read_output(output_message).stderr
|
|
104
|
-
).to eq("errors\r\n")
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
context 'response doc writing output to host' do
|
|
109
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_host_call] }
|
|
110
|
-
let(:test_data) do
|
|
111
|
-
"<Obj RefId='0'><MS><I64 N='ci'>-100</I64><Obj N='mi' RefId='1'><TN RefId='0'>" \
|
|
112
|
-
'<T>System.Management.Automation.Remoting.RemoteHostMethodId</T><T>System.Enum</T>' \
|
|
113
|
-
'<T>System.ValueType</T><T>System.Object</T></TN><ToString>WriteLine</ToString>' \
|
|
114
|
-
"<I32>18</I32></Obj><Obj N='mp' RefId='2'><TN RefId='1'>" \
|
|
115
|
-
'<T>System.Collections.ArrayList</T><T>System.Object</T></TN><LST><S>output</S></LST>' \
|
|
116
|
-
'</Obj></MS></Obj>'
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it 'outputs to stdout' do
|
|
120
|
-
expect(
|
|
121
|
-
subject.read_output(output_message).stdout
|
|
122
|
-
).to eq("output\r\n")
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
describe '#read_message' do
|
|
128
|
-
context 'do not wait for done state' do
|
|
129
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
130
|
-
|
|
131
|
-
it 'outputs the message in an array' do
|
|
132
|
-
expect(subject.read_message(output_message).length).to eq(1)
|
|
133
|
-
expect(subject.read_message(output_message)[0].data).to end_with(message.data)
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context 'read in a block' do
|
|
138
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
139
|
-
|
|
140
|
-
it 'outputs the message in an array' do
|
|
141
|
-
subject.read_message(output_message) do |msg|
|
|
142
|
-
expect(msg.data).to end_with(message.data)
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
context 'wait for done state' do
|
|
148
|
-
let(:message_type) { WinRM::PSRP::Message::MESSAGE_TYPES[:pipeline_output] }
|
|
149
|
-
let(:test_data_xml_not_done) { test_data_xml_template_not_done.result(binding) }
|
|
150
|
-
let(:test_data_xml_done) { test_data_xml_template.result(binding) }
|
|
151
|
-
|
|
152
|
-
before do
|
|
153
|
-
allow(transport).to receive(:send_request).and_return(
|
|
154
|
-
REXML::Document.new(test_data_xml_not_done),
|
|
155
|
-
REXML::Document.new(test_data_xml_done)
|
|
156
|
-
)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it 'outputs two messages' do
|
|
160
|
-
expect(subject.read_message(output_message, true).length).to eq(2)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
it 'outputs the first message' do
|
|
164
|
-
expect(subject.read_message(output_message, true)[0].data).to end_with(message.data)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
it 'outputs the second message' do
|
|
168
|
-
expect(subject.read_message(output_message, true)[1].data).to end_with(message.data)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
describe WinRM::PSRP::UUID do
|
|
3
|
-
subject(:uuid_helper) do
|
|
4
|
-
Object.new.extend(WinRM::PSRP::UUID)
|
|
5
|
-
end
|
|
6
|
-
context 'uuid is nil' do
|
|
7
|
-
uuid = nil
|
|
8
|
-
it 'should return an empty byte array' do
|
|
9
|
-
bytes = uuid_helper.uuid_to_windows_guid_bytes(uuid)
|
|
10
|
-
expect(bytes).to eq([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
context 'uuid 08785e96-eb1b-4a74-a767-7b56e8f13ea9 with lower case letters' do
|
|
14
|
-
uuid = '08785e96-eb1b-4a74-a767-7b56e8f13ea9'
|
|
15
|
-
it 'should return a Windows GUID struct compatible little endian byte array' do
|
|
16
|
-
bytes = uuid_helper.uuid_to_windows_guid_bytes(uuid)
|
|
17
|
-
expect(bytes).to eq([150, 94, 120, 8, 27, 235, 116, 74, 167, 103, 123, 86, 232, 241, 62, 169])
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
context 'uuid 045F9E19D-8B77-4394-AB0C-197497661668 with upper case letters' do
|
|
21
|
-
uuid = '45F9E19D-8B77-4394-AB0C-197497661668'
|
|
22
|
-
it 'should return a Windows GUID struct compatible little endian byte array' do
|
|
23
|
-
bytes = uuid_helper.uuid_to_windows_guid_bytes(uuid)
|
|
24
|
-
expect(bytes).to eq(
|
|
25
|
-
[157, 225, 249, 69, 119, 139, 148, 67, 171, 12, 25, 116, 151, 102, 22, 104])
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|