ruby_smb 1.0.0 → 1.1.0

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 (171) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.travis.yml +4 -1
  4. data/README.md +35 -47
  5. data/examples/enum_registry_key.rb +28 -0
  6. data/examples/enum_registry_values.rb +30 -0
  7. data/examples/pipes.rb +2 -1
  8. data/examples/read_registry_key_value.rb +32 -0
  9. data/lib/ruby_smb/client/authentication.rb +43 -25
  10. data/lib/ruby_smb/client/echo.rb +20 -2
  11. data/lib/ruby_smb/client/negotiation.rb +27 -12
  12. data/lib/ruby_smb/client/tree_connect.rb +20 -14
  13. data/lib/ruby_smb/client/utils.rb +2 -2
  14. data/lib/ruby_smb/client/winreg.rb +46 -0
  15. data/lib/ruby_smb/client.rb +28 -4
  16. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  17. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  18. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  19. data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
  20. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  21. data/lib/ruby_smb/dcerpc/request.rb +28 -9
  22. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
  23. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  24. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  25. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  26. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  27. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  28. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  29. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  30. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  31. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  32. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  33. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  34. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  35. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  36. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  37. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
  38. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  39. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  40. data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
  41. data/lib/ruby_smb/dcerpc.rb +38 -0
  42. data/lib/ruby_smb/dispatcher/socket.rb +3 -1
  43. data/lib/ruby_smb/error.rb +40 -1
  44. data/lib/ruby_smb/generic_packet.rb +33 -4
  45. data/lib/ruby_smb/smb1/file.rb +67 -11
  46. data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
  47. data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
  48. data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
  49. data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
  50. data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
  51. data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
  52. data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
  53. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
  54. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
  55. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
  56. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
  57. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
  58. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
  59. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
  60. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
  61. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
  62. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
  63. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
  64. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
  65. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +2 -1
  66. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
  67. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -1
  68. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
  69. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
  70. data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
  71. data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
  72. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
  73. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
  74. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
  75. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
  76. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
  77. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
  78. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
  79. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
  80. data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
  81. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
  82. data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
  83. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
  84. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
  85. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
  86. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
  87. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  88. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
  89. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +2 -5
  90. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
  91. data/lib/ruby_smb/smb1/pipe.rb +86 -5
  92. data/lib/ruby_smb/smb1/tree.rb +40 -2
  93. data/lib/ruby_smb/smb2/file.rb +97 -1
  94. data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
  95. data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
  96. data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
  97. data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
  98. data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
  99. data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
  100. data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
  101. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
  102. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
  103. data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
  104. data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
  105. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +2 -5
  106. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +2 -1
  107. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
  108. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
  109. data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
  110. data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
  111. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  112. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
  113. data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
  114. data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
  115. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +2 -5
  116. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +8 -2
  117. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
  118. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
  119. data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
  120. data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
  121. data/lib/ruby_smb/smb2/pipe.rb +98 -11
  122. data/lib/ruby_smb/smb2/tree.rb +44 -6
  123. data/lib/ruby_smb/version.rb +1 -1
  124. data/lib/ruby_smb.rb +0 -1
  125. data/ruby_smb.gemspec +3 -3
  126. data/spec/lib/ruby_smb/client_spec.rb +271 -11
  127. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  128. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  129. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
  130. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  131. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
  132. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  133. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  134. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  135. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  136. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
  137. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  138. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  139. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  140. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  141. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  142. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
  143. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  144. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
  145. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  146. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  147. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
  148. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  149. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
  150. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  151. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +3 -1
  152. data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
  153. data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
  154. data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
  155. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
  156. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
  157. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
  158. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
  159. data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
  160. data/spec/lib/ruby_smb/smb2/file_spec.rb +295 -2
  161. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
  162. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
  163. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +8 -0
  164. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +322 -145
  165. data/spec/lib/ruby_smb/smb2/tree_spec.rb +214 -0
  166. data.tar.gz.sig +0 -0
  167. metadata +70 -11
  168. metadata.gz.sig +0 -0
  169. data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
  170. data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
  171. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -0,0 +1,39 @@
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::QueryInfoKeyRequest do
8
+ subject(:packet) { described_class.new }
9
+
10
+ it { is_expected.to respond_to :hkey }
11
+ it { is_expected.to respond_to :lp_class }
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 '#lp_class' do
25
+ it 'is a RrpUnicodeString structure' do
26
+ expect(packet.lp_class).to be_a RubySMB::Dcerpc::RrpUnicodeString
27
+ end
28
+
29
+ it 'has an initial value of 0' do
30
+ expect(packet.lp_class).to eq(0)
31
+ end
32
+ end
33
+
34
+ describe '#initialize_instance' do
35
+ it 'sets #opnum to REG_QUERY_INFO_KEY constant' do
36
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_QUERY_INFO_KEY)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,113 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::QueryInfoKeyResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :lp_class }
5
+ it { is_expected.to respond_to :pad }
6
+ it { is_expected.to respond_to :lpc_sub_keys }
7
+ it { is_expected.to respond_to :lpc_max_sub_key_len }
8
+ it { is_expected.to respond_to :lpc_max_class_len }
9
+ it { is_expected.to respond_to :lpc_values }
10
+ it { is_expected.to respond_to :lpcb_max_value_name_len }
11
+ it { is_expected.to respond_to :lpcb_max_value_len }
12
+ it { is_expected.to respond_to :lpcb_security_descriptor }
13
+ it { is_expected.to respond_to :lpft_last_write_time }
14
+ it { is_expected.to respond_to :error_status }
15
+ it { is_expected.to respond_to :opnum }
16
+
17
+ it 'is little endian' do
18
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
19
+ end
20
+
21
+ describe '#lp_class' do
22
+ it 'is a RrpUnicodeString structure' do
23
+ expect(packet.lp_class).to be_a RubySMB::Dcerpc::RrpUnicodeString
24
+ end
25
+
26
+ it 'has an initial value of 0' do
27
+ expect(packet.lp_class).to eq(0)
28
+ end
29
+ end
30
+
31
+ describe '#pad' do
32
+ it 'is a string' do
33
+ expect(packet.pad).to be_a BinData::String
34
+ end
35
+
36
+ it 'should keep #lpc_sub_keys 4-byte aligned' do
37
+ packet.lp_class = 'test'
38
+ expect(packet.lpc_sub_keys.abs_offset % 4).to eq 0
39
+ end
40
+ end
41
+
42
+ describe '#lpc_sub_keys' do
43
+ it 'is a 32-bit unsigned integer' do
44
+ expect(packet.lpc_sub_keys).to be_a BinData::Uint32le
45
+ end
46
+ end
47
+
48
+ describe '#lpc_max_sub_key_len' do
49
+ it 'is a 32-bit unsigned integer' do
50
+ expect(packet.lpc_max_sub_key_len).to be_a BinData::Uint32le
51
+ end
52
+ end
53
+
54
+ describe '#lpc_max_class_len' do
55
+ it 'is a 32-bit unsigned integer' do
56
+ expect(packet.lpc_max_class_len).to be_a BinData::Uint32le
57
+ end
58
+ end
59
+
60
+ describe '#lpc_values' do
61
+ it 'is a 32-bit unsigned integer' do
62
+ expect(packet.lpc_values).to be_a BinData::Uint32le
63
+ end
64
+ end
65
+
66
+ describe '#lpcb_max_value_name_len' do
67
+ it 'is a 32-bit unsigned integer' do
68
+ expect(packet.lpcb_max_value_name_len).to be_a BinData::Uint32le
69
+ end
70
+ end
71
+
72
+ describe '#lpcb_max_value_len' do
73
+ it 'is a 32-bit unsigned integer' do
74
+ expect(packet.lpcb_max_value_len).to be_a BinData::Uint32le
75
+ end
76
+ end
77
+
78
+ describe '#lpcb_security_descriptor' do
79
+ it 'is a 32-bit unsigned integer' do
80
+ expect(packet.lpcb_security_descriptor).to be_a BinData::Uint32le
81
+ end
82
+ end
83
+
84
+ describe '#lpft_last_write_time' do
85
+ it 'is a FileTime structure' do
86
+ expect(packet.lpft_last_write_time).to be_a RubySMB::Field::FileTime
87
+ end
88
+ end
89
+
90
+ describe '#error_status' do
91
+ it 'is a 32-bit unsigned integer' do
92
+ expect(packet.error_status).to be_a BinData::Uint32le
93
+ end
94
+ end
95
+
96
+ describe '#initialize_instance' do
97
+ it 'sets #opnum to REG_QUERY_INFO_KEY constant' do
98
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_QUERY_INFO_KEY)
99
+ end
100
+ end
101
+
102
+ describe '#pad_length' do
103
+ it 'returns 0 when #lpc_sub_keys is already 4-byte aligned' do
104
+ packet.lp_class = 'align'
105
+ expect(packet.pad_length).to eq 0
106
+ end
107
+
108
+ it 'returns 2 when #lpc_sub_keys is only 2-byte aligned' do
109
+ packet.lp_class = 'align' + 'A'
110
+ expect(packet.pad_length).to eq 2
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,88 @@
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::QueryValueRequest do
8
+ subject(:packet) { described_class.new }
9
+
10
+ it { is_expected.to respond_to :hkey }
11
+ it { is_expected.to respond_to :lp_value_name }
12
+ it { is_expected.to respond_to :pad }
13
+ it { is_expected.to respond_to :lp_type }
14
+ it { is_expected.to respond_to :lp_data }
15
+ it { is_expected.to respond_to :lpcb_data }
16
+ it { is_expected.to respond_to :lpcb_len }
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 '#lp_value_name' do
30
+ it 'is a RrpUnicodeString structure' do
31
+ expect(packet.lp_value_name).to be_a RubySMB::Dcerpc::RrpUnicodeString
32
+ end
33
+ end
34
+
35
+ describe '#pad' do
36
+ it 'is a string' do
37
+ expect(packet.pad).to be_a BinData::String
38
+ end
39
+
40
+ it 'should keep #lp_type 4-byte aligned' do
41
+ packet.lp_value_name = 'test'
42
+ expect(packet.lp_type.abs_offset % 4).to eq 0
43
+ end
44
+ end
45
+
46
+ describe '#lp_type' do
47
+ it 'is a NdrLpDword structure' do
48
+ expect(packet.lp_type).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
49
+ end
50
+ end
51
+
52
+ describe '#lp_data' do
53
+ it 'is a NdrLpByte structure' do
54
+ expect(packet.lp_data).to be_a RubySMB::Dcerpc::Ndr::NdrLpByte
55
+ end
56
+ end
57
+
58
+ describe '#lpcb_data' do
59
+ it 'is a NdrLpDword structure' do
60
+ expect(packet.lpcb_data).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
61
+ end
62
+ end
63
+
64
+ describe '#lpcb_len' do
65
+ it 'is a NdrLpDword structure' do
66
+ expect(packet.lpcb_len).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
67
+ end
68
+ end
69
+
70
+ describe '#initialize_instance' do
71
+ it 'sets #opnum to REG_QUERY_VALUE constant' do
72
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_QUERY_VALUE)
73
+ end
74
+ end
75
+
76
+ describe '#pad_length' do
77
+ it 'returns 0 when #lp_type is already 4-byte aligned' do
78
+ packet.lp_value_name = 'align'
79
+ expect(packet.pad_length).to eq 0
80
+ end
81
+
82
+ it 'returns 2 when #lp_type is only 2-byte aligned' do
83
+ packet.lp_value_name = 'align' + 'A'
84
+ expect(packet.pad_length).to eq 2
85
+ end
86
+ end
87
+ end
88
+
@@ -0,0 +1,150 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::QueryValueResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :lp_type }
5
+ it { is_expected.to respond_to :lp_data }
6
+ it { is_expected.to respond_to :pad }
7
+ it { is_expected.to respond_to :lpcb_data }
8
+ it { is_expected.to respond_to :lpcb_len }
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
+ describe '#lp_type' do
17
+ it 'is a NdrLpDword structure' do
18
+ expect(packet.lp_type).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
19
+ end
20
+ end
21
+
22
+ describe '#lp_data' do
23
+ it 'is a NdrLpByte structure' do
24
+ expect(packet.lp_data).to be_a RubySMB::Dcerpc::Ndr::NdrLpByte
25
+ end
26
+ end
27
+
28
+ describe '#pad' do
29
+ it 'is a string' do
30
+ expect(packet.pad).to be_a BinData::String
31
+ end
32
+
33
+ it 'should keep #lpcb_data 4-byte aligned' do
34
+ packet.lp_data.bytes = 'spec_test'.bytes
35
+ expect(packet.lpcb_data.abs_offset % 4).to eq 0
36
+ end
37
+ end
38
+
39
+ describe '#lpcb_data' do
40
+ it 'is a NdrLpDword structure' do
41
+ expect(packet.lpcb_data).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
42
+ end
43
+ end
44
+
45
+ describe '#lpcb_len' do
46
+ it 'is a NdrLpDword structure' do
47
+ expect(packet.lpcb_len).to be_a RubySMB::Dcerpc::Ndr::NdrLpDword
48
+ end
49
+ end
50
+
51
+ describe '#error_status' do
52
+ it 'is a 32-bit unsigned integer' do
53
+ expect(packet.error_status).to be_a BinData::Uint32le
54
+ end
55
+ end
56
+
57
+ describe '#initialize_instance' do
58
+ it 'sets #opnum to REG_QUERY_VALUE constant' do
59
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_QUERY_VALUE)
60
+ end
61
+ end
62
+
63
+ describe '#pad_length' do
64
+ it 'returns 0 when #lpcb_data is already 4-byte aligned' do
65
+ packet.lp_data.bytes = 'aligned.'.bytes
66
+ expect(packet.pad_length).to eq 0
67
+ end
68
+
69
+ it 'returns 2 when #lpcb_data is only 2-byte aligned' do
70
+ packet.lp_data.bytes = 'not aligned'.bytes
71
+ expect(packet.pad_length).to eq 1
72
+ end
73
+ end
74
+
75
+ describe '#data' do
76
+ context 'when #lp_type is 1 (unicode null-terminated string)' do
77
+ it 'returns the expected value' do
78
+ str = 'spec test string'.encode('utf-16le')
79
+ packet.lp_type = 1
80
+ packet.lp_data.bytes = str.bytes
81
+ expect(packet.data).to eq(str)
82
+ end
83
+ end
84
+
85
+ context 'when #lp_type is 2 (unicode null-terminated string with unexpanded references to environment variables)' do
86
+ it 'returns the expected value' do
87
+ str = '/%PATH%/foo'.encode('utf-16le')
88
+ packet.lp_type = 2
89
+ packet.lp_data.bytes = str.bytes
90
+ expect(packet.data).to eq(str)
91
+ end
92
+ end
93
+
94
+ context 'when #lp_type is 3 (binary data)' do
95
+ it 'returns the expected value' do
96
+ bytes = [0xFF, 0xEE, 0xDD, 0xCC].pack('C*')
97
+ packet.lp_type = 3
98
+ packet.lp_data.bytes = bytes.bytes
99
+ expect(packet.data).to eq(bytes)
100
+ end
101
+ end
102
+
103
+ context 'when #lp_type is 4 (a 32-bit number in little-endian format)' do
104
+ it 'returns the expected value' do
105
+ number = 12345
106
+ packet.lp_type = 4
107
+ packet.lp_data.bytes = [number].pack('V').bytes
108
+ expect(packet.data).to eq(number)
109
+ end
110
+ end
111
+
112
+ context 'when #lp_type is 5 (a 32-bit number in big-endian format)' do
113
+ it 'returns the expected value' do
114
+ number = 12345
115
+ packet.lp_type = 5
116
+ packet.lp_data.bytes = [number].pack('N').bytes
117
+ expect(packet.data).to eq(number)
118
+ end
119
+ end
120
+
121
+ context 'when #lp_type is 7 (a sequence of unicode null-terminated strings, terminated by an empty string)' do
122
+ it 'returns the expected value' do
123
+ str_array = ['String1', 'String2', 'String3', 'LastString'].map {|v| v.encode('utf-16le')}
124
+ null_byte = "\0".encode('utf-16le')
125
+ str = (str_array + [null_byte]).join(null_byte)
126
+ packet.lp_type = 7
127
+ packet.lp_data.bytes = str.bytes
128
+ expect(packet.data).to eq(str_array)
129
+ end
130
+ end
131
+
132
+ context 'when #lp_type is 11 (a 64-bit number in little-endian format)' do
133
+ it 'returns the expected value' do
134
+ number = 0x1234567812345678
135
+ packet.lp_type = 11
136
+ packet.lp_data.bytes = [number].pack('Q<').bytes
137
+ expect(packet.data).to eq(number)
138
+ end
139
+ end
140
+
141
+ context 'when #lp_type is an unknown value' do
142
+ it 'returns an empty string' do
143
+ str = 'test'
144
+ packet.lp_type = 6
145
+ packet.lp_data.bytes = str.bytes
146
+ expect(packet.data).to eq('')
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,32 @@
1
+ RSpec.describe RubySMB::Dcerpc::Winreg::Regsam do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :reserved }
5
+ it { is_expected.to respond_to :key_create_link }
6
+ it { is_expected.to respond_to :key_notify }
7
+ it { is_expected.to respond_to :key_enumerate_sub_keys }
8
+ it { is_expected.to respond_to :key_create_sub_key }
9
+ it { is_expected.to respond_to :key_set_value }
10
+ it { is_expected.to respond_to :key_query_value }
11
+ it { is_expected.to respond_to :reserved2 }
12
+ it { is_expected.to respond_to :key_wow64_32key }
13
+ it { is_expected.to respond_to :key_wow64_64key }
14
+ it { is_expected.to respond_to :reserved3 }
15
+ it { is_expected.to respond_to :synchronize }
16
+ it { is_expected.to respond_to :write_owner }
17
+ it { is_expected.to respond_to :write_dac }
18
+ it { is_expected.to respond_to :read_control }
19
+ it { is_expected.to respond_to :delete_access }
20
+ it { is_expected.to respond_to :generic_read }
21
+ it { is_expected.to respond_to :generic_write }
22
+ it { is_expected.to respond_to :generic_execute }
23
+ it { is_expected.to respond_to :generic_all }
24
+ it { is_expected.to respond_to :reserved4 }
25
+ it { is_expected.to respond_to :maximum }
26
+ it { is_expected.to respond_to :system_security }
27
+
28
+
29
+ it 'is little endian' do
30
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
31
+ end
32
+ end