ruby_smb 1.0.3 → 2.0.1

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 (200) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.travis.yml +3 -2
  5. data/Gemfile +6 -2
  6. data/README.md +35 -47
  7. data/examples/enum_registry_key.rb +28 -0
  8. data/examples/enum_registry_values.rb +30 -0
  9. data/examples/negotiate.rb +51 -8
  10. data/examples/pipes.rb +2 -1
  11. data/examples/read_file_encryption.rb +56 -0
  12. data/examples/read_registry_key_value.rb +32 -0
  13. data/lib/ruby_smb.rb +4 -1
  14. data/lib/ruby_smb/client.rb +233 -22
  15. data/lib/ruby_smb/client/authentication.rb +70 -33
  16. data/lib/ruby_smb/client/echo.rb +20 -2
  17. data/lib/ruby_smb/client/encryption.rb +62 -0
  18. data/lib/ruby_smb/client/negotiation.rb +172 -24
  19. data/lib/ruby_smb/client/signing.rb +19 -0
  20. data/lib/ruby_smb/client/tree_connect.rb +24 -18
  21. data/lib/ruby_smb/client/utils.rb +8 -7
  22. data/lib/ruby_smb/client/winreg.rb +46 -0
  23. data/lib/ruby_smb/crypto.rb +30 -0
  24. data/lib/ruby_smb/dcerpc.rb +38 -0
  25. data/lib/ruby_smb/dcerpc/bind.rb +2 -2
  26. data/lib/ruby_smb/dcerpc/bind_ack.rb +2 -2
  27. data/lib/ruby_smb/dcerpc/error.rb +3 -0
  28. data/lib/ruby_smb/dcerpc/ndr.rb +95 -16
  29. data/lib/ruby_smb/dcerpc/pdu_header.rb +1 -1
  30. data/lib/ruby_smb/dcerpc/request.rb +28 -9
  31. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +35 -0
  32. data/lib/ruby_smb/dcerpc/srvsvc.rb +10 -0
  33. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +9 -0
  34. data/lib/ruby_smb/dcerpc/winreg.rb +340 -0
  35. data/lib/ruby_smb/dcerpc/winreg/close_key_request.rb +24 -0
  36. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +27 -0
  37. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +45 -0
  38. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +42 -0
  39. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +39 -0
  40. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +36 -0
  41. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +34 -0
  42. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +25 -0
  43. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +43 -0
  44. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +35 -0
  45. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +27 -0
  46. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +40 -0
  47. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +39 -0
  48. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +57 -0
  49. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +40 -0
  50. data/lib/ruby_smb/dispatcher/socket.rb +4 -3
  51. data/lib/ruby_smb/error.rb +68 -2
  52. data/lib/ruby_smb/generic_packet.rb +33 -4
  53. data/lib/ruby_smb/smb1/commands.rb +1 -1
  54. data/lib/ruby_smb/smb1/file.rb +66 -15
  55. data/lib/ruby_smb/smb1/packet/close_request.rb +2 -5
  56. data/lib/ruby_smb/smb1/packet/close_response.rb +2 -1
  57. data/lib/ruby_smb/smb1/packet/echo_request.rb +2 -4
  58. data/lib/ruby_smb/smb1/packet/echo_response.rb +2 -1
  59. data/lib/ruby_smb/smb1/packet/empty_packet.rb +10 -1
  60. data/lib/ruby_smb/smb1/packet/logoff_request.rb +2 -4
  61. data/lib/ruby_smb/smb1/packet/logoff_response.rb +2 -1
  62. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +2 -5
  63. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +3 -7
  64. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +4 -4
  65. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +2 -4
  66. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +2 -1
  67. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +2 -1
  68. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +2 -1
  69. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +2 -4
  70. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +2 -1
  71. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +2 -5
  72. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +2 -1
  73. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -1
  74. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +3 -2
  75. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +2 -5
  76. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +3 -2
  77. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_request.rb +0 -1
  78. data/lib/ruby_smb/smb1/packet/trans/peek_nmpipe_response.rb +3 -2
  79. data/lib/ruby_smb/smb1/packet/trans/request.rb +2 -5
  80. data/lib/ruby_smb/smb1/packet/trans/response.rb +2 -1
  81. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_request.rb +1 -1
  82. data/lib/ruby_smb/smb1/packet/trans/transact_nmpipe_response.rb +1 -1
  83. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +2 -1
  84. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +8 -2
  85. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +2 -1
  86. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +8 -2
  87. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +2 -1
  88. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +2 -1
  89. data/lib/ruby_smb/smb1/packet/trans2/request.rb +2 -4
  90. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +2 -4
  91. data/lib/ruby_smb/smb1/packet/trans2/response.rb +2 -1
  92. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +2 -1
  93. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +2 -1
  94. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +2 -4
  95. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +13 -3
  96. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  97. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -1
  98. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +3 -6
  99. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +2 -1
  100. data/lib/ruby_smb/smb1/pipe.rb +87 -6
  101. data/lib/ruby_smb/smb1/tree.rb +50 -3
  102. data/lib/ruby_smb/smb2/bit_field/session_flags.rb +2 -1
  103. data/lib/ruby_smb/smb2/bit_field/share_flags.rb +6 -4
  104. data/lib/ruby_smb/smb2/file.rb +103 -25
  105. data/lib/ruby_smb/smb2/negotiate_context.rb +108 -0
  106. data/lib/ruby_smb/smb2/packet.rb +2 -0
  107. data/lib/ruby_smb/smb2/packet/close_request.rb +2 -4
  108. data/lib/ruby_smb/smb2/packet/close_response.rb +2 -1
  109. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +41 -0
  110. data/lib/ruby_smb/smb2/packet/create_request.rb +2 -4
  111. data/lib/ruby_smb/smb2/packet/create_response.rb +2 -1
  112. data/lib/ruby_smb/smb2/packet/echo_request.rb +2 -4
  113. data/lib/ruby_smb/smb2/packet/echo_response.rb +2 -1
  114. data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -3
  115. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +2 -5
  116. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +2 -1
  117. data/lib/ruby_smb/smb2/packet/logoff_request.rb +2 -4
  118. data/lib/ruby_smb/smb2/packet/logoff_response.rb +2 -1
  119. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +51 -17
  120. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +52 -5
  121. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +2 -4
  122. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +8 -2
  123. data/lib/ruby_smb/smb2/packet/read_request.rb +2 -4
  124. data/lib/ruby_smb/smb2/packet/read_response.rb +2 -1
  125. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  126. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -1
  127. data/lib/ruby_smb/smb2/packet/set_info_request.rb +2 -4
  128. data/lib/ruby_smb/smb2/packet/set_info_response.rb +2 -1
  129. data/lib/ruby_smb/smb2/packet/transform_header.rb +84 -0
  130. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +93 -10
  131. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +10 -22
  132. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +2 -4
  133. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +2 -1
  134. data/lib/ruby_smb/smb2/packet/write_request.rb +2 -4
  135. data/lib/ruby_smb/smb2/packet/write_response.rb +2 -1
  136. data/lib/ruby_smb/smb2/pipe.rb +86 -12
  137. data/lib/ruby_smb/smb2/smb2_header.rb +1 -1
  138. data/lib/ruby_smb/smb2/tree.rb +65 -21
  139. data/lib/ruby_smb/version.rb +1 -1
  140. data/ruby_smb.gemspec +5 -3
  141. data/spec/lib/ruby_smb/client_spec.rb +1612 -108
  142. data/spec/lib/ruby_smb/crypto_spec.rb +25 -0
  143. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +2 -2
  144. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +2 -2
  145. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +410 -0
  146. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +50 -7
  147. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +98 -0
  148. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +13 -0
  149. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +60 -0
  150. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_request_spec.rb +28 -0
  151. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +36 -0
  152. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +108 -0
  153. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +97 -0
  154. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +94 -0
  155. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +82 -0
  156. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +74 -0
  157. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +35 -0
  158. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +90 -0
  159. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +38 -0
  160. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +39 -0
  161. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +113 -0
  162. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +88 -0
  163. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +150 -0
  164. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +32 -0
  165. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +710 -0
  166. data/spec/lib/ruby_smb/dcerpc_spec.rb +81 -0
  167. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +2 -2
  168. data/spec/lib/ruby_smb/error_spec.rb +59 -0
  169. data/spec/lib/ruby_smb/generic_packet_spec.rb +52 -4
  170. data/spec/lib/ruby_smb/smb1/file_spec.rb +191 -2
  171. data/spec/lib/ruby_smb/smb1/packet/empty_packet_spec.rb +68 -0
  172. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +2 -2
  173. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +2 -2
  174. data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +2 -2
  175. data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +1 -1
  176. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +11 -2
  177. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +11 -2
  178. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +40 -0
  179. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +272 -149
  180. data/spec/lib/ruby_smb/smb1/tree_spec.rb +44 -7
  181. data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +9 -0
  182. data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +27 -0
  183. data/spec/lib/ruby_smb/smb2/file_spec.rb +323 -6
  184. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +332 -0
  185. data/spec/lib/ruby_smb/smb2/packet/compression_transform_header_spec.rb +108 -0
  186. data/spec/lib/ruby_smb/smb2/packet/error_packet_spec.rb +78 -0
  187. data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +138 -3
  188. data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +120 -2
  189. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +8 -0
  190. data/spec/lib/ruby_smb/smb2/packet/transform_header_spec.rb +220 -0
  191. data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +339 -9
  192. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +3 -22
  193. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +286 -149
  194. data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +2 -2
  195. data/spec/lib/ruby_smb/smb2/tree_spec.rb +261 -2
  196. metadata +191 -83
  197. metadata.gz.sig +0 -0
  198. data/lib/ruby_smb/smb1/dcerpc.rb +0 -67
  199. data/lib/ruby_smb/smb2/dcerpc.rb +0 -70
  200. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +0 -37
@@ -69,11 +69,51 @@ RSpec.describe RubySMB::Dcerpc::Request do
69
69
  expect(packet.stub).to be_a BinData::Choice
70
70
  end
71
71
 
72
- context 'with a NetShareEnumAll stub' do
72
+ context 'with a Srvsvc endpoint' do
73
+ let(:host) { '1.2.3.4' }
74
+ let(:packet) do
75
+ described_class.new(
76
+ { :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL },
77
+ { :endpoint => 'Srvsvc', :host => host }
78
+ )
79
+ end
80
+
81
+ it 'uses endpoint parameter to select a Srvsvc stub packet' do
82
+ expect(packet.stub.selection).to eq('Srvsvc')
83
+ end
84
+
85
+ it 'selects the expected packet structure' do
86
+ expect(packet.stub).to eq(RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: host))
87
+ end
88
+ end
89
+
90
+ context 'with a Winreg endpoint' do
91
+ let(:opnum) { RubySMB::Dcerpc::Winreg::OPEN_HKCR }
92
+ let(:packet) do
93
+ described_class.new(
94
+ { :opnum => opnum },
95
+ { :endpoint => 'Winreg' }
96
+ )
97
+ end
73
98
 
74
- it 'uses opnum as a selector' do
75
- packet = described_class.new({ :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL }, host: '1.2.3.4')
76
- expect(packet.stub.selection).to eq(packet.opnum)
99
+ it 'uses endpoint parameter to select a Winreg stub packet' do
100
+ expect(packet.stub.selection).to eq('Winreg')
101
+ end
102
+
103
+ it 'selects the expected packet structure' do
104
+ expect(packet.stub).to eq(RubySMB::Dcerpc::Winreg::OpenRootKeyRequest.new(opnum: opnum))
105
+ end
106
+ end
107
+
108
+ context 'with an unknown endpoint' do
109
+ let(:packet) do
110
+ described_class.new(
111
+ { :endpoint => 'Unknown' }
112
+ )
113
+ end
114
+
115
+ it 'sets #stub to an empty string' do
116
+ expect(packet.stub).to eq('')
77
117
  end
78
118
  end
79
119
  end
@@ -102,13 +142,16 @@ RSpec.describe RubySMB::Dcerpc::Request do
102
142
  end
103
143
 
104
144
  it 'reads its own binary representation and output the same packet' do
105
- packet = described_class.new({ :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL }, host: '1.2.3.4')
145
+ packet = described_class.new(
146
+ { :opnum => RubySMB::Dcerpc::Srvsvc::NET_SHARE_ENUM_ALL },
147
+ { :endpoint => 'Srvsvc', :host => '1.2.3.4' }
148
+ )
106
149
  packet.pdu_header.pfc_flags.object_uuid = 1
107
150
  packet.object = '8a885d04-1ceb-11c9-9fe8-08002b104860'
108
151
  packet.auth_verifier = '123456'
109
152
  packet.pdu_header.auth_length = 6
110
153
  binary = packet.to_binary_s
111
- expect(described_class.read(binary)).to eq(packet)
154
+ packet2 = described_class.new( { :endpoint => 'Srvsvc' } )
155
+ expect(packet2.read(binary)).to eq(packet)
112
156
  end
113
157
  end
114
-
@@ -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
+