ruby_smb 3.3.6 → 3.3.8

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +14 -0
  4. data/examples/registry_key_security_descriptor.rb +109 -0
  5. data/lib/ruby_smb/client/winreg.rb +12 -0
  6. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  7. data/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_request.rb +22 -0
  8. data/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_response.rb +23 -0
  9. data/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_request.rb +26 -0
  10. data/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_response.rb +25 -0
  11. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_request.rb +24 -0
  12. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_response.rb +23 -0
  13. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_request.rb +24 -0
  14. data/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_response.rb +23 -0
  15. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_request.rb +23 -0
  16. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_response.rb +23 -0
  17. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_request.rb +23 -0
  18. data/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_response.rb +23 -0
  19. data/lib/ruby_smb/dcerpc/lsarpc.rb +634 -2
  20. data/lib/ruby_smb/dcerpc/ndr.rb +10 -4
  21. data/lib/ruby_smb/dcerpc/request.rb +26 -16
  22. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +1 -1
  23. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +1 -1
  24. data/lib/ruby_smb/dcerpc/winreg/get_key_security_request.rb +26 -0
  25. data/lib/ruby_smb/dcerpc/winreg/get_key_security_response.rb +26 -0
  26. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +2 -0
  27. data/lib/ruby_smb/dcerpc/winreg/set_key_security_request.rb +26 -0
  28. data/lib/ruby_smb/dcerpc/winreg/set_key_security_response.rb +25 -0
  29. data/lib/ruby_smb/dcerpc/winreg.rb +121 -9
  30. data/lib/ruby_smb/field/security_descriptor.rb +17 -0
  31. data/lib/ruby_smb/version.rb +1 -1
  32. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_request_spec.rb +40 -0
  33. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_close_handle_response_spec.rb +46 -0
  34. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_request_spec.rb +69 -0
  35. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_lookup_sids_response_spec.rb +56 -0
  36. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_request_spec.rb +68 -0
  37. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy2_response_spec.rb +46 -0
  38. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_request_spec.rb +68 -0
  39. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_open_policy_response_spec.rb +45 -0
  40. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_request_spec.rb +47 -0
  41. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy2_response_spec.rb +54 -0
  42. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_request_spec.rb +46 -0
  43. data/spec/lib/ruby_smb/dcerpc/lsarpc/lsar_query_information_policy_response_spec.rb +53 -0
  44. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +80 -0
  45. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +267 -18
  46. data.tar.gz.sig +0 -0
  47. metadata +44 -3
  48. metadata.gz.sig +0 -0
@@ -0,0 +1,68 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicy2Request do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :system_name }
7
+ it { is_expected.to respond_to :object_attributes }
8
+ it { is_expected.to respond_to :access_mask }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#system_name' do
18
+ it 'is an NdrWideStringzPtr structure' do
19
+ expect(packet.system_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringzPtr
20
+ end
21
+ end
22
+ describe '#object_attributes' do
23
+ it 'is an LsaprObjectAttributes structure' do
24
+ expect(packet.object_attributes).to be_a RubySMB::Dcerpc::Lsarpc::LsaprObjectAttributes
25
+ end
26
+ end
27
+ describe '#access_mask' do
28
+ it 'is an NdrUint32 structure' do
29
+ expect(packet.access_mask).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
30
+ end
31
+ end
32
+ describe '#initialize_instance' do
33
+ it 'sets #opnum to LSAR_OPEN_POLICY2 constant' do
34
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY2)
35
+ end
36
+ end
37
+ it 'reads itself' do
38
+ new_class = described_class.new(
39
+ system_name: 'Example_System',
40
+ object_attributes: {
41
+ security_quality_of_service: {
42
+ impersonation_level: 0,
43
+ security_context_tracking_mode: 0
44
+ }
45
+ },
46
+ access_mask: 0
47
+ )
48
+ expect(packet.read(new_class.to_binary_s)).to eq(
49
+ {
50
+ system_name: 'Example_System'.encode('UTF-16LE'),
51
+ object_attributes: {
52
+ len: 24,
53
+ root_directory: :null,
54
+ object_name: :null,
55
+ attributes: 0,
56
+ security_descriptor: :null,
57
+ security_quality_of_service: {
58
+ len: 12,
59
+ impersonation_level: 0,
60
+ security_context_tracking_mode: 0,
61
+ effective_only: 0
62
+ }
63
+ },
64
+ access_mask: 0
65
+ }
66
+ )
67
+ end
68
+ end
@@ -0,0 +1,46 @@
1
+
2
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicy2Response do
3
+ subject(:packet) { described_class.new }
4
+
5
+ it { is_expected.to respond_to :policy_handle }
6
+ it { is_expected.to respond_to :error_status }
7
+ it { is_expected.to respond_to :opnum }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+ it 'is a BinData::Record' do
13
+ expect(packet).to be_a(BinData::Record)
14
+ end
15
+ describe '#policy_handle' do
16
+ it 'is an LsaprHandle structure' do
17
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
18
+ end
19
+ end
20
+ describe '#error_status' do
21
+ it 'is a NdrUint32' do
22
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
23
+ end
24
+ end
25
+ describe '#initialize_instance' do
26
+ it 'sets #opnum to LSAR_OPEN_POLICY2 constant' do
27
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY2)
28
+ end
29
+ end
30
+ it 'reads itself' do
31
+ new_class = described_class.new(
32
+ policy_handle: {
33
+ context_handle_attributes: 0,
34
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
35
+ },
36
+ error_status: 0
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_handle: {
40
+ context_handle_attributes: 0,
41
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
42
+ },
43
+ error_status: 0
44
+ )
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicyRequest do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :system_name }
7
+ it { is_expected.to respond_to :object_attributes }
8
+ it { is_expected.to respond_to :access_mask }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#system_name' do
18
+ it 'is an NdrWideStringPtr structure' do
19
+ expect(packet.system_name).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringPtr
20
+ end
21
+ end
22
+ describe '#object_attributes' do
23
+ it 'is an LsaprObjectAttributes structure' do
24
+ expect(packet.object_attributes).to be_a RubySMB::Dcerpc::Lsarpc::LsaprObjectAttributes
25
+ end
26
+ end
27
+ describe '#access_mask' do
28
+ it 'is an NdrUint32 structure' do
29
+ expect(packet.access_mask).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
30
+ end
31
+ end
32
+ describe '#initialize_instance' do
33
+ it 'sets #opnum to LSAR_OPEN_POLICY constant' do
34
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY)
35
+ end
36
+ end
37
+ it 'reads itself' do
38
+ new_class = described_class.new(
39
+ system_name: 'Example_System',
40
+ object_attributes: {
41
+ security_quality_of_service: {
42
+ impersonation_level: 0,
43
+ security_context_tracking_mode: 0
44
+ }
45
+ },
46
+ access_mask: 0
47
+ )
48
+ expect(packet.read(new_class.to_binary_s)).to eq(
49
+ {
50
+ system_name: 'Example_System'.encode('UTF-16LE'),
51
+ object_attributes: {
52
+ len: 24,
53
+ root_directory: :null,
54
+ object_name: :null,
55
+ attributes: 0,
56
+ security_descriptor: :null,
57
+ security_quality_of_service: {
58
+ len: 12,
59
+ impersonation_level: 0,
60
+ security_context_tracking_mode: 0,
61
+ effective_only: 0
62
+ }
63
+ },
64
+ access_mask: 0
65
+ }
66
+ )
67
+ end
68
+ end
@@ -0,0 +1,45 @@
1
+
2
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarOpenPolicyResponse do
3
+ subject(:packet) { described_class.new }
4
+
5
+ it { is_expected.to respond_to :policy_handle }
6
+ it { is_expected.to respond_to :error_status }
7
+ it { is_expected.to respond_to :opnum }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+ it 'is a BinData::Record' do
13
+ expect(packet).to be_a(BinData::Record)
14
+ end
15
+ describe '#policy_handle' do
16
+ it 'is an LsaprHandle structure' do
17
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
18
+ end
19
+ end
20
+ describe '#error_status' do
21
+ it 'is a NdrUint32' do
22
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
23
+ end
24
+ end
25
+ describe '#initialize_instance' do
26
+ it 'sets #opnum to LSAR_OPEN_POLICY constant' do
27
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_OPEN_POLICY)
28
+ end
29
+ end
30
+ it 'reads itself' do
31
+ new_class = described_class.new(
32
+ policy_handle: {
33
+ context_handle_attributes: 0,
34
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
35
+ }
36
+ )
37
+ expect(packet.read(new_class.to_binary_s)).to eq(
38
+ policy_handle: {
39
+ context_handle_attributes: 0,
40
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
41
+ },
42
+ error_status: 0
43
+ )
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicy2Request do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_handle }
7
+ it { is_expected.to respond_to :information_class }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_handle' do
17
+ it 'is an LsaprHandle structure' do
18
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
19
+ end
20
+ end
21
+ describe '#information_class' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.information_class).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY2 constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY2)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_handle: {
34
+ context_handle_attributes: 0,
35
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
36
+ },
37
+ information_class: 0
38
+ )
39
+ expect(packet.read(new_class.to_binary_s)).to eq(
40
+ policy_handle: {
41
+ context_handle_attributes: 0,
42
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
43
+ },
44
+ information_class: 0
45
+ )
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+ require 'ruby_smb/dcerpc/lsarpc'
3
+
4
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicy2Response do
5
+ subject(:packet) { described_class.new }
6
+
7
+ it { is_expected.to respond_to :policy_information }
8
+ it { is_expected.to respond_to :error_status }
9
+ it { is_expected.to respond_to :opnum }
10
+
11
+ it 'is little endian' do
12
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
+ end
14
+ it 'is a BinData::Record' do
15
+ expect(packet).to be_a(BinData::Record)
16
+ end
17
+ describe '#policy_information' do
18
+ it 'is an LsaprPolicyInformationPtr structure' do
19
+ expect(packet.policy_information).to be_a RubySMB::Dcerpc::Lsarpc::LsaprPolicyInformationPtr
20
+ end
21
+ end
22
+ describe '#error_status' do
23
+ it 'is an NdrUint32 structure' do
24
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
25
+ end
26
+ end
27
+ describe '#initialize_instance' do
28
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY2 constant' do
29
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY2)
30
+ end
31
+ end
32
+ it 'reads itself' do
33
+ new_class = described_class.new(
34
+ policy_information: {
35
+ policy_information_class: 1,
36
+ policy_information: {}
37
+ }
38
+ )
39
+ expect(packet.read(new_class.to_binary_s)).to eq(
40
+ policy_information: {
41
+ policy_information_class: 1,
42
+ policy_information: {
43
+ audit_log_percent_full: 0,
44
+ maximum_log_size: 0,
45
+ audit_retention_period: 0,
46
+ audit_log_full_shutdown_in_progress: 0,
47
+ time_to_shutdown: 0,
48
+ next_audit_record_id: 0
49
+ }
50
+ },
51
+ error_status: 0
52
+ )
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicyRequest do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_handle }
7
+ it { is_expected.to respond_to :information_class }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_handle' do
17
+ it 'is an LsaprHandle structure' do
18
+ expect(packet.policy_handle).to be_a RubySMB::Dcerpc::Lsarpc::LsaprHandle
19
+ end
20
+ end
21
+ describe '#information_class' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.information_class).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_handle: {
34
+ context_handle_attributes: 0,
35
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
36
+ }
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_handle: {
40
+ context_handle_attributes: 0,
41
+ context_handle_uuid: "fc873b90-d9a9-46a4-b9ea-f44bb1c272a7"
42
+ },
43
+ information_class: 0
44
+ )
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ require 'ruby_smb/dcerpc/ndr'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Lsarpc::LsarQueryInformationPolicyResponse do
4
+ subject(:packet) { described_class.new }
5
+
6
+ it { is_expected.to respond_to :policy_information }
7
+ it { is_expected.to respond_to :error_status }
8
+ it { is_expected.to respond_to :opnum }
9
+
10
+ it 'is little endian' do
11
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
12
+ end
13
+ it 'is a BinData::Record' do
14
+ expect(packet).to be_a(BinData::Record)
15
+ end
16
+ describe '#policy_information' do
17
+ it 'is an LsaprPolicyInformationPtr structure' do
18
+ expect(packet.policy_information).to be_a RubySMB::Dcerpc::Lsarpc::LsaprPolicyInformationPtr
19
+ end
20
+ end
21
+ describe '#error_status' do
22
+ it 'is an NdrUint32 structure' do
23
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
24
+ end
25
+ end
26
+ describe '#initialize_instance' do
27
+ it 'sets #opnum to LSAR_QUERY_INFORMATION_POLICY constant' do
28
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Lsarpc::LSAR_QUERY_INFORMATION_POLICY)
29
+ end
30
+ end
31
+ it 'reads itself' do
32
+ new_class = described_class.new(
33
+ policy_information: {
34
+ policy_information_class: 1,
35
+ policy_information: {}
36
+ }
37
+ )
38
+ expect(packet.read(new_class.to_binary_s)).to eq(
39
+ policy_information: {
40
+ policy_information_class: 1,
41
+ policy_information: {
42
+ audit_log_percent_full: 0,
43
+ maximum_log_size: 0,
44
+ audit_retention_period: 0,
45
+ audit_log_full_shutdown_in_progress: 0,
46
+ time_to_shutdown: 0,
47
+ next_audit_record_id: 0
48
+ }
49
+ },
50
+ error_status: 0
51
+ )
52
+ end
53
+ end
@@ -1352,6 +1352,15 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarString do
1352
1352
  }
1353
1353
  let(:value) { 'ABCD' }
1354
1354
  end
1355
+ context 'with an empty string' do
1356
+ it_behaves_like 'a NDR String', conformant: false, char_size: 1, null_terminated: false do
1357
+ let(:binary_stream) {
1358
+ "\x00\x00\x00\x00"\
1359
+ "\x00\x00\x00\x00".b
1360
+ }
1361
+ let(:value) { '' }
1362
+ end
1363
+ end
1355
1364
  end
1356
1365
 
1357
1366
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarStringz do
@@ -1368,6 +1377,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarStringz do
1368
1377
  }
1369
1378
  let(:value) { 'ABCD' }
1370
1379
  end
1380
+ context 'with an empty string' do
1381
+ it_behaves_like 'a NDR String', conformant: false, char_size: 1, null_terminated: true do
1382
+ let(:binary_stream) {
1383
+ "\x00\x00\x00\x00"\
1384
+ "\x01\x00\x00\x00"\
1385
+ "\x00".b
1386
+ }
1387
+ let(:value) { '' }
1388
+ end
1389
+ end
1371
1390
  end
1372
1391
 
1373
1392
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideString do
@@ -1383,6 +1402,15 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideString do
1383
1402
  }
1384
1403
  let(:value) { 'ABCD'.encode('utf-16le') }
1385
1404
  end
1405
+ context 'with an empty string' do
1406
+ it_behaves_like 'a NDR String', conformant: false, char_size: 2, null_terminated: false do
1407
+ let(:binary_stream) {
1408
+ "\x00\x00\x00\x00"\
1409
+ "\x00\x00\x00\x00".b
1410
+ }
1411
+ let(:value) { '' }
1412
+ end
1413
+ end
1386
1414
  end
1387
1415
 
1388
1416
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideStringz do
@@ -1398,6 +1426,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrVarWideStringz do
1398
1426
  }
1399
1427
  let(:value) { 'ABCD'.encode('utf-16le') }
1400
1428
  end
1429
+ context 'with an empty string' do
1430
+ it_behaves_like 'a NDR String', conformant: false, char_size: 2, null_terminated: true do
1431
+ let(:binary_stream) {
1432
+ "\x00\x00\x00\x00"\
1433
+ "\x01\x00\x00\x00"\
1434
+ "\x00\x00".b
1435
+ }
1436
+ let(:value) { '' }
1437
+ end
1438
+ end
1401
1439
  end
1402
1440
 
1403
1441
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarString do
@@ -1415,6 +1453,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarString do
1415
1453
  }
1416
1454
  let(:value) { 'ABCD' }
1417
1455
  end
1456
+ context 'with an empty string' do
1457
+ it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: false do
1458
+ let(:binary_stream) {
1459
+ "\x00\x00\x00\x00"\
1460
+ "\x00\x00\x00\x00"\
1461
+ "\x00\x00\x00\x00".b
1462
+ }
1463
+ let(:value) { '' }
1464
+ end
1465
+ end
1418
1466
  end
1419
1467
 
1420
1468
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarStringz do
@@ -1432,6 +1480,17 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarStringz do
1432
1480
  }
1433
1481
  let(:value) { 'ABCD' }
1434
1482
  end
1483
+ context 'with an empty string' do
1484
+ it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: true do
1485
+ let(:binary_stream) {
1486
+ "\x01\x00\x00\x00"\
1487
+ "\x00\x00\x00\x00"\
1488
+ "\x01\x00\x00\x00"\
1489
+ "\x00".b
1490
+ }
1491
+ let(:value) { '' }
1492
+ end
1493
+ end
1435
1494
  end
1436
1495
 
1437
1496
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideString do
@@ -1448,6 +1507,16 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideString do
1448
1507
  }
1449
1508
  let(:value) { 'ABCD'.encode('utf-16le') }
1450
1509
  end
1510
+ context 'with an empty string' do
1511
+ it_behaves_like 'a NDR String', conformant: true, char_size: 2, null_terminated: false do
1512
+ let(:binary_stream) {
1513
+ "\x00\x00\x00\x00"\
1514
+ "\x00\x00\x00\x00"\
1515
+ "\x00\x00\x00\x00".b
1516
+ }
1517
+ let(:value) { '' }
1518
+ end
1519
+ end
1451
1520
  end
1452
1521
 
1453
1522
  RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideStringz do
@@ -1464,6 +1533,17 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrConfVarWideStringz do
1464
1533
  }
1465
1534
  let(:value) { 'ABCD'.encode('utf-16le') }
1466
1535
  end
1536
+ context 'with an empty string' do
1537
+ it_behaves_like 'a NDR String', conformant: true, char_size: 1, null_terminated: true do
1538
+ let(:binary_stream) {
1539
+ "\x01\x00\x00\x00"\
1540
+ "\x00\x00\x00\x00"\
1541
+ "\x01\x00\x00\x00"\
1542
+ "\x00\x00".b
1543
+ }
1544
+ let(:value) { '' }
1545
+ end
1546
+ end
1467
1547
  end
1468
1548
 
1469
1549