ruby_smb 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +4 -1
  5. data/README.md +35 -47
  6. data/examples/enum_registry_key.rb +28 -0
  7. data/examples/enum_registry_values.rb +30 -0
  8. data/examples/pipes.rb +2 -1
  9. data/examples/read_registry_key_value.rb +32 -0
  10. data/lib/ruby_smb.rb +0 -1
  11. data/lib/ruby_smb/client.rb +2 -0
  12. data/lib/ruby_smb/client/winreg.rb +46 -0
  13. data/lib/ruby_smb/dcerpc.rb +38 -0
  14. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  15. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  16. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  17. data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
  18. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  19. data/lib/ruby_smb/dcerpc/request.rb +28 -9
  20. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
  21. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  22. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  23. data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
  24. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  25. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  26. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  27. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  28. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  29. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  30. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  31. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  32. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  33. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  34. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  35. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  36. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
  37. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  38. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  39. data/lib/ruby_smb/smb1/file.rb +2 -0
  40. data/lib/ruby_smb/smb1/pipe.rb +78 -2
  41. data/lib/ruby_smb/smb2/packet/error_packet.rb +2 -4
  42. data/lib/ruby_smb/smb2/pipe.rb +89 -2
  43. data/lib/ruby_smb/version.rb +1 -1
  44. data/ruby_smb.gemspec +3 -3
  45. data/spec/lib/ruby_smb/client_spec.rb +148 -0
  46. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  47. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  48. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
  49. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  50. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
  51. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  52. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  53. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  54. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  55. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
  56. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  57. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  58. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  59. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  60. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  61. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
  62. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  63. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
  64. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  65. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  66. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
  67. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  68. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
  69. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  70. data/spec/lib/ruby_smb/smb1/file_spec.rb +9 -1
  71. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +210 -148
  72. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +3 -24
  73. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +256 -145
  74. metadata +66 -9
  75. metadata.gz.sig +0 -0
  76. data/lib/ruby_smb/smb1/dcerpc.rb +0 -72
  77. data/lib/ruby_smb/smb2/dcerpc.rb +0 -75
@@ -0,0 +1,98 @@
1
+ RSpec.describe RubySMB::Dcerpc::RrpUnicodeString do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :buffer_length }
5
+ it { is_expected.to respond_to :maximum_length }
6
+ it { is_expected.to respond_to :buffer }
7
+
8
+ it 'is little endian' do
9
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
10
+ end
11
+
12
+ describe '#buffer_length' do
13
+ it 'should be a 16-bit unsigned integer' do
14
+ expect(packet.buffer_length).to be_a BinData::Uint16le
15
+ end
16
+
17
+ it 'is set to 0 when #buffer in empty' do
18
+ expect(packet.buffer_length).to eq(0)
19
+ end
20
+ end
21
+
22
+ describe '#maximum_length' do
23
+ it 'should be a 16-bit unsigned integer' do
24
+ expect(packet.maximum_length).to be_a BinData::Uint16le
25
+ end
26
+ end
27
+
28
+ describe '#buffer' do
29
+ it 'should be a NdrLpStr' do
30
+ expect(packet.buffer).to be_a RubySMB::Dcerpc::Ndr::NdrLpStr
31
+ end
32
+ end
33
+
34
+ describe '#get' do
35
+ it 'returns #buffer' do
36
+ packet.buffer = 'spec_test'
37
+ expect(packet.get).to eq(RubySMB::Dcerpc::Ndr::NdrLpStr.new('spec_test'))
38
+ end
39
+ end
40
+
41
+ describe '#set' do
42
+ it 'sets #buffer to the expected value' do
43
+ packet.set('spec_test')
44
+ expect(packet.buffer).to eq(RubySMB::Dcerpc::Ndr::NdrLpStr.new('spec_test'))
45
+ end
46
+
47
+ it 'sets #buffer_length to the expected value' do
48
+ packet.set('spec_test')
49
+ expect(packet.buffer_length).to eq(('spec_test'.size + 1) * 2)
50
+ end
51
+
52
+ it 'sets #maximum_length to the expected value' do
53
+ packet.set('spec_test')
54
+ expect(packet.maximum_length).to eq(('spec_test'.size + 1) * 2)
55
+ end
56
+
57
+ context 'when the value is 0' do
58
+ it 'sets #buffer_length to 0' do
59
+ packet.set(0)
60
+ expect(packet.buffer_length).to eq(0)
61
+ end
62
+
63
+ it 'sets #maximum_length to 0' do
64
+ packet.set(0)
65
+ expect(packet.maximum_length).to eq(0)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ RSpec.describe RubySMB::Dcerpc::PrrpUnicodeString do
72
+ it 'is NdrTopLevelFullPointer subclass' do
73
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrTopLevelFullPointer
74
+ end
75
+
76
+ subject(:packet) { described_class.new }
77
+
78
+ it { is_expected.to respond_to :referent }
79
+
80
+ it 'is little endian' do
81
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
82
+ end
83
+
84
+ describe '#referent' do
85
+ it 'is a RrpUnicodeString' do
86
+ expect(packet.referent).to be_a RubySMB::Dcerpc::RrpUnicodeString
87
+ end
88
+
89
+ it 'exists if superclass #referent_identifier is not zero' do
90
+ expect(packet.referent?).to be true
91
+ end
92
+
93
+ it 'does not exist if superclass #referent_identifier is zero' do
94
+ packet.referent_identifier = 0
95
+ expect(packet.referent?).to be false
96
+ end
97
+ end
98
+ end
@@ -15,11 +15,18 @@ RSpec.describe RubySMB::Dcerpc::Srvsvc::NetShareEnumAll do
15
15
  it { is_expected.to respond_to :max_buffer }
16
16
  it { is_expected.to respond_to :resume_referent_id }
17
17
  it { is_expected.to respond_to :resume_handle }
18
+ it { is_expected.to respond_to :opnum }
18
19
 
19
20
  it 'is little endian' do
20
21
  expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
21
22
  end
22
23
 
24
+ context 'when \'host\' parameter is not provided' do
25
+ it 'raises an ArgumentError' do
26
+ expect { described_class.new }.to raise_error(ArgumentError)
27
+ end
28
+ end
29
+
23
30
  describe '#referent_id' do
24
31
  it 'should be a 32-bit unsigned integer' do
25
32
  expect(packet.referent_id).to be_a BinData::Uint32le
@@ -156,6 +163,12 @@ RSpec.describe RubySMB::Dcerpc::Srvsvc::NetShareEnumAll do
156
163
  end
157
164
  end
158
165
 
166
+ describe '#initialize_instance' do
167
+ it 'sets #opnum to REG_CLOSE_KEY constant' do
168
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL)
169
+ end
170
+ end
171
+
159
172
  describe '#pad_length' do
160
173
  it 'returns 0 when #level is already 4-byte aligned' do
161
174
  expect(packet.pad_length).to eq 0
@@ -0,0 +1,60 @@
1
+ RSpec.describe RubySMB::Dcerpc::Srvsvc do
2
+ let(:srvsvc) do
3
+ RubySMB::SMB1::Pipe.new(
4
+ tree: double('Tree'),
5
+ response: RubySMB::SMB1::Packet::NtCreateAndxResponse.new,
6
+ name: 'srvsvc'
7
+ )
8
+ end
9
+
10
+ describe '#net_share_enum_all' do
11
+ let(:host) { '1.2.3.4' }
12
+ let(:request_packet) { double('NetShareEnumAll request packet') }
13
+ let(:dcerpc_response) { double('DCERPC response') }
14
+ let(:shares) do
15
+ [
16
+ ["C$", "DISK", "Default share"],
17
+ ["Shared", "DISK", ""],
18
+ ["IPC$", "IPC", "Remote IPC"],
19
+ ["ADMIN$", "DISK", "Remote Admin"]
20
+ ]
21
+ end
22
+
23
+ before :example do
24
+ allow(srvsvc).to receive(:bind)
25
+ allow(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to receive(:new).and_return(request_packet)
26
+ allow(srvsvc).to receive(:dcerpc_request).and_return(dcerpc_response)
27
+ allow(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to receive(:parse_response).and_return(shares)
28
+ end
29
+
30
+ it 'calls #bind with the expected arguments' do
31
+ srvsvc.net_share_enum_all(host)
32
+ expect(srvsvc).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Srvsvc)
33
+ end
34
+
35
+ it 'creates the expected NetShareEnumAll packet' do
36
+ srvsvc.net_share_enum_all(host)
37
+ expect(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to have_received(:new).with(host: host)
38
+ end
39
+
40
+ it 'calls #request with the expected arguments' do
41
+ srvsvc.net_share_enum_all(host)
42
+ expect(srvsvc).to have_received(:dcerpc_request).with(request_packet)
43
+ end
44
+
45
+ it 'parse the response with NetShareEnumAll #parse_response method' do
46
+ srvsvc.net_share_enum_all(host)
47
+ expect(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll).to have_received(:parse_response).with(dcerpc_response)
48
+ end
49
+
50
+ it 'returns the remote shares' do
51
+ output = [
52
+ {:name=>"C$", :type=>"DISK", :comment=>"Default share"},
53
+ {:name=>"Shared", :type=>"DISK", :comment=>""},
54
+ {:name=>"IPC$", :type=>"IPC", :comment=>"Remote IPC"},
55
+ {:name=>"ADMIN$", :type=>"DISK", :comment=>"Remote Admin"},
56
+ ]
57
+ expect(srvsvc.net_share_enum_all(host)).to eq(output)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,28 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::RpcHkey do
2
+ it 'is NdrContextHandle subclass' do
3
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrContextHandle
4
+ end
5
+ end
6
+
7
+ RSpec.describe RubySMB::Dcerpc::Winreg::CloseKeyRequest do
8
+ subject(:packet) { described_class.new }
9
+
10
+ it { is_expected.to respond_to :hkey }
11
+ it { is_expected.to respond_to :opnum }
12
+
13
+ it 'is little endian' do
14
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
15
+ end
16
+
17
+ describe '#hkey' do
18
+ it 'is a RpcHkey structure' do
19
+ expect(packet.hkey).to be_a RubySMB::Dcerpc::Winreg::RpcHkey
20
+ end
21
+ end
22
+
23
+ describe '#initialize_instance' do
24
+ it 'sets #opnum to REG_CLOSE_KEY constant' do
25
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_CLOSE_KEY)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::RpcHkey do
2
+ it 'is NdrContextHandle subclass' do
3
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrContextHandle
4
+ end
5
+ end
6
+
7
+ RSpec.describe RubySMB::Dcerpc::Winreg::CloseKeyResponse do
8
+ subject(:packet) { described_class.new }
9
+
10
+ it { is_expected.to respond_to :hkey }
11
+ it { is_expected.to respond_to :error_status }
12
+ it { is_expected.to respond_to :opnum }
13
+
14
+ it 'is little endian' do
15
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
16
+ end
17
+
18
+ describe '#hkey' do
19
+ it 'is a RpcHkey structure' do
20
+ expect(packet.hkey).to be_a RubySMB::Dcerpc::Winreg::RpcHkey
21
+ end
22
+ end
23
+
24
+ describe '#error_status' do
25
+ it 'is a 32-bit unsigned integer' do
26
+ expect(packet.error_status).to be_a BinData::Uint32le
27
+ end
28
+ end
29
+
30
+ describe '#initialize_instance' do
31
+ it 'sets #opnum to REG_CLOSE_KEY constant' do
32
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_CLOSE_KEY)
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,108 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::RpcHkey do
2
+ it 'is NdrContextHandle subclass' do
3
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrContextHandle
4
+ end
5
+ end
6
+
7
+ RSpec.describe RubySMB::Dcerpc::Winreg::EnumKeyRequest do
8
+ subject(:packet) { described_class.new }
9
+
10
+ it { is_expected.to respond_to :hkey }
11
+ it { is_expected.to respond_to :dw_index }
12
+ it { is_expected.to respond_to :lp_name }
13
+ it { is_expected.to respond_to :pad1 }
14
+ it { is_expected.to respond_to :lp_class }
15
+ it { is_expected.to respond_to :pad2 }
16
+ it { is_expected.to respond_to :lpft_last_write_time }
17
+ it { is_expected.to respond_to :opnum }
18
+
19
+ it 'is little endian' do
20
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
21
+ end
22
+
23
+ describe '#hkey' do
24
+ it 'is a RpcHkey structure' do
25
+ expect(packet.hkey).to be_a RubySMB::Dcerpc::Winreg::RpcHkey
26
+ end
27
+ end
28
+
29
+ describe '#dw_index' do
30
+ it 'is a 32-bit unsigned integer' do
31
+ expect(packet.dw_index).to be_a BinData::Uint32le
32
+ end
33
+ end
34
+
35
+ describe '#lp_name' do
36
+ it 'is a RrpUnicodeString structure' do
37
+ expect(packet.lp_name).to be_a RubySMB::Dcerpc::RrpUnicodeString
38
+ end
39
+ end
40
+
41
+ describe '#pad1' do
42
+ it 'is a string' do
43
+ expect(packet.pad1).to be_a BinData::String
44
+ end
45
+
46
+ it 'should keep #lp_class 4-byte aligned' do
47
+ packet.lp_name = "test"
48
+ expect(packet.lp_class.abs_offset % 4).to eq 0
49
+ end
50
+ end
51
+
52
+ describe '#lp_class' do
53
+ it 'is a PrrpUnicodeString structure' do
54
+ expect(packet.lp_class).to be_a RubySMB::Dcerpc::PrrpUnicodeString
55
+ end
56
+
57
+ it 'has a initial value of 0' do
58
+ expect(packet.lp_class).to eq(0)
59
+ end
60
+ end
61
+
62
+ describe '#pad2' do
63
+ it 'is a string' do
64
+ expect(packet.pad2).to be_a BinData::String
65
+ end
66
+
67
+ it 'should keep #lpft_last_write_time 4-byte aligned' do
68
+ packet.lp_class = "test"
69
+ expect(packet.lpft_last_write_time.abs_offset % 4).to eq 0
70
+ end
71
+ end
72
+
73
+ describe '#lpft_last_write_time' do
74
+ it 'is a NdrLpFileTime structure' do
75
+ expect(packet.lpft_last_write_time).to be_a RubySMB::Dcerpc::Ndr::NdrLpFileTime
76
+ end
77
+ end
78
+
79
+ describe '#initialize_instance' do
80
+ it 'sets #opnum to REG_ENUM_KEY constant' do
81
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_ENUM_KEY)
82
+ end
83
+ end
84
+
85
+ describe '#pad_length1' do
86
+ it 'returns 0 when #lp_class is already 4-byte aligned' do
87
+ packet.lp_name = 'align'
88
+ expect(packet.pad_length1).to eq 0
89
+ end
90
+
91
+ it 'returns 2 when #lp_class is only 2-byte aligned' do
92
+ packet.lp_name = 'align' + 'A'
93
+ expect(packet.pad_length1).to eq 2
94
+ end
95
+ end
96
+
97
+ describe '#pad_length2' do
98
+ it 'returns 0 when #lpft_last_write_time is already 4-byte aligned' do
99
+ packet.lp_class = 'align'
100
+ expect(packet.pad_length2).to eq 0
101
+ end
102
+
103
+ it 'returns 2 when #lpft_last_write_time is only 2-byte aligned' do
104
+ packet.lp_class = 'align' + 'A'
105
+ expect(packet.pad_length2).to eq 2
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,97 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::EnumKeyResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :lp_name }
5
+ it { is_expected.to respond_to :pad1 }
6
+ it { is_expected.to respond_to :lp_class }
7
+ it { is_expected.to respond_to :pad2 }
8
+ it { is_expected.to respond_to :lpft_last_write_time }
9
+ it { is_expected.to respond_to :error_status }
10
+ it { is_expected.to respond_to :opnum }
11
+
12
+ it 'is little endian' do
13
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
14
+ end
15
+
16
+
17
+ describe '#lp_name' do
18
+ it 'is a RrpUnicodeString structure' do
19
+ expect(packet.lp_name).to be_a RubySMB::Dcerpc::RrpUnicodeString
20
+ end
21
+ end
22
+
23
+ describe '#pad1' do
24
+ it 'is a string' do
25
+ expect(packet.pad1).to be_a BinData::String
26
+ end
27
+
28
+ it 'should keep #lp_class 4-byte aligned' do
29
+ packet.lp_name = "test"
30
+ expect(packet.lp_class.abs_offset % 4).to eq 0
31
+ end
32
+ end
33
+
34
+ describe '#lp_class' do
35
+ it 'is a PrrpUnicodeString structure' do
36
+ expect(packet.lp_class).to be_a RubySMB::Dcerpc::PrrpUnicodeString
37
+ end
38
+
39
+ it 'has a initial value of 0' do
40
+ expect(packet.lp_class).to eq(0)
41
+ end
42
+ end
43
+
44
+ describe '#pad2' do
45
+ it 'is a string' do
46
+ expect(packet.pad2).to be_a BinData::String
47
+ end
48
+
49
+ it 'should keep #lpft_last_write_time 4-byte aligned' do
50
+ packet.lp_class = "test"
51
+ expect(packet.lpft_last_write_time.abs_offset % 4).to eq 0
52
+ end
53
+ end
54
+
55
+ describe '#lpft_last_write_time' do
56
+ it 'is a NdrLpFileTime structure' do
57
+ expect(packet.lpft_last_write_time).to be_a RubySMB::Dcerpc::Ndr::NdrLpFileTime
58
+ end
59
+ end
60
+
61
+ describe '#error_status' do
62
+ it 'is a 32-bit unsigned integer' do
63
+ expect(packet.error_status).to be_a BinData::Uint32le
64
+ end
65
+ end
66
+
67
+ describe '#initialize_instance' do
68
+ it 'sets #opnum to REG_ENUM_KEY constant' do
69
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_ENUM_KEY)
70
+ end
71
+ end
72
+
73
+ describe '#pad_length1' do
74
+ it 'returns 0 when #lp_class is already 4-byte aligned' do
75
+ packet.lp_name = 'align'
76
+ expect(packet.pad_length1).to eq 0
77
+ end
78
+
79
+ it 'returns 2 when #lp_class is only 2-byte aligned' do
80
+ packet.lp_name = 'align' + 'A'
81
+ expect(packet.pad_length1).to eq 2
82
+ end
83
+ end
84
+
85
+ describe '#pad_length2' do
86
+ it 'returns 0 when #lpft_last_write_time is already 4-byte aligned' do
87
+ packet.lp_class = 'align'
88
+ expect(packet.pad_length2).to eq 0
89
+ end
90
+
91
+ it 'returns 2 when #lpft_last_write_time is only 2-byte aligned' do
92
+ packet.lp_class = 'align' + 'A'
93
+ expect(packet.pad_length2).to eq 2
94
+ end
95
+ end
96
+ end
97
+