ruby_smb 2.0.2 → 3.0.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 (285) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +46 -0
  4. data/README.md +0 -1
  5. data/examples/anonymous_auth.rb +3 -3
  6. data/examples/append_file.rb +10 -8
  7. data/examples/auth_capture.rb +71 -0
  8. data/examples/authenticate.rb +9 -5
  9. data/examples/delete_file.rb +8 -6
  10. data/examples/dump_secrets_from_sid.rb +207 -0
  11. data/examples/enum_domain_users.rb +75 -0
  12. data/examples/enum_registry_key.rb +5 -4
  13. data/examples/enum_registry_values.rb +5 -4
  14. data/examples/get_computer_info.rb +42 -0
  15. data/examples/list_directory.rb +8 -6
  16. data/examples/negotiate_with_netbios_service.rb +9 -5
  17. data/examples/net_share_enum_all.rb +6 -4
  18. data/examples/pipes.rb +11 -12
  19. data/examples/query_service_status.rb +102 -0
  20. data/examples/read_file.rb +8 -6
  21. data/examples/read_registry_key_value.rb +6 -5
  22. data/examples/rename_file.rb +9 -7
  23. data/examples/tree_connect.rb +7 -5
  24. data/examples/write_file.rb +9 -7
  25. data/lib/ruby_smb/client/authentication.rb +5 -10
  26. data/lib/ruby_smb/client/echo.rb +2 -4
  27. data/lib/ruby_smb/client/negotiation.rb +13 -16
  28. data/lib/ruby_smb/client/tree_connect.rb +2 -4
  29. data/lib/ruby_smb/client/utils.rb +16 -10
  30. data/lib/ruby_smb/client/winreg.rb +1 -1
  31. data/lib/ruby_smb/client.rb +102 -75
  32. data/lib/ruby_smb/compression/lznt1.rb +164 -0
  33. data/lib/ruby_smb/compression.rb +7 -0
  34. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  35. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  36. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  37. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  38. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  39. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  40. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  41. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  42. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  43. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  44. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  45. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  46. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  47. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  48. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  49. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  50. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  51. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  52. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  53. data/lib/ruby_smb/dcerpc/error.rb +20 -0
  54. data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
  55. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
  56. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
  57. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
  58. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
  59. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
  61. data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
  62. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  63. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  64. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  65. data/lib/ruby_smb/dcerpc/request.rb +85 -19
  66. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  67. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  68. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
  69. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  70. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  79. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  80. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  81. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  82. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  83. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  84. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  85. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  86. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  87. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  88. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  89. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  90. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  91. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  92. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  93. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +36 -0
  94. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
  95. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
  96. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
  97. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
  98. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
  99. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
  100. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
  101. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
  102. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
  103. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
  104. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
  105. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
  106. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
  107. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
  108. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
  109. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
  110. data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
  111. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  112. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  113. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +62 -0
  114. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
  115. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
  116. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  117. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  118. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  119. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  120. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  121. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +6 -7
  122. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  123. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
  124. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  125. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
  126. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  127. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  128. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +28 -0
  129. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
  130. data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
  131. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  132. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  133. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  134. data/lib/ruby_smb/dcerpc.rb +45 -11
  135. data/lib/ruby_smb/dialect.rb +45 -0
  136. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  137. data/lib/ruby_smb/dispatcher/socket.rb +2 -2
  138. data/lib/ruby_smb/error.rb +21 -5
  139. data/lib/ruby_smb/field/file_time.rb +1 -1
  140. data/lib/ruby_smb/field/string16.rb +5 -1
  141. data/lib/ruby_smb/field/stringz16.rb +17 -1
  142. data/lib/ruby_smb/generic_packet.rb +11 -1
  143. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  144. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  145. data/lib/ruby_smb/gss/provider.rb +35 -0
  146. data/lib/ruby_smb/gss.rb +56 -63
  147. data/lib/ruby_smb/nbss/session_header.rb +4 -4
  148. data/lib/ruby_smb/ntlm.rb +61 -0
  149. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  150. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  151. data/lib/ruby_smb/server/server_client.rb +162 -0
  152. data/lib/ruby_smb/server.rb +54 -0
  153. data/lib/ruby_smb/signing.rb +59 -0
  154. data/lib/ruby_smb/smb1/file.rb +10 -25
  155. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  156. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  157. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  158. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
  159. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
  160. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
  161. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
  162. data/lib/ruby_smb/smb1/pipe.rb +12 -6
  163. data/lib/ruby_smb/smb1/tree.rb +13 -9
  164. data/lib/ruby_smb/smb2/file.rb +33 -33
  165. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  166. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
  167. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  168. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  169. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  170. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  171. data/lib/ruby_smb/smb2/pipe.rb +13 -6
  172. data/lib/ruby_smb/smb2/tree.rb +21 -11
  173. data/lib/ruby_smb/smb2.rb +3 -1
  174. data/lib/ruby_smb/version.rb +1 -1
  175. data/lib/ruby_smb.rb +5 -3
  176. data/spec/lib/ruby_smb/client_spec.rb +199 -86
  177. data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
  178. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  179. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  180. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  181. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3977 -239
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
  187. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
  188. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
  189. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  190. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  191. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  192. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  193. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  194. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +162 -0
  195. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  196. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  197. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  198. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  199. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  200. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  201. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  210. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  211. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  212. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  213. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +168 -0
  214. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
  215. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
  216. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
  217. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
  218. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
  230. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
  231. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  232. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  233. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +73 -0
  234. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
  235. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
  236. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  237. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  238. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  239. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  240. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  241. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -20
  242. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  243. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
  244. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  245. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  246. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +18 -42
  247. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  248. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
  249. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
  250. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
  251. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  252. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  253. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  254. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
  255. data/spec/lib/ruby_smb/error_spec.rb +34 -5
  256. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  257. data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
  258. data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  261. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  262. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  263. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
  264. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  265. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  266. data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
  267. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
  268. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
  269. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
  270. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
  271. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
  272. data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
  273. data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
  274. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  275. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
  276. data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
  277. data/spec/spec_helper.rb +1 -1
  278. data/spec/support/bin_helper.rb +9 -0
  279. data.tar.gz.sig +0 -0
  280. metadata +229 -23
  281. metadata.gz.sig +0 -0
  282. data/.travis.yml +0 -6
  283. data/lib/ruby_smb/client/signing.rb +0 -64
  284. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
  285. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
@@ -0,0 +1,47 @@
1
+ RSpec.describe RubySMB::Dcerpc::Svcctl::StartServiceWRequest do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :h_service }
5
+ it { is_expected.to respond_to :argc }
6
+ it { is_expected.to respond_to :argv }
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 '#h_service' do
13
+ it 'is a ScRpcHandle structure' do
14
+ expect(packet.h_service).to be_a RubySMB::Dcerpc::Svcctl::ScRpcHandle
15
+ end
16
+ end
17
+
18
+ describe '#argc' do
19
+ it 'is a NdrUint32' do
20
+ expect(packet.argc).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
21
+ end
22
+ end
23
+
24
+ describe '#argv' do
25
+ it 'is a Ndr::NdrConfArray of Ndr::NdrWideStringPtr elements' do
26
+ expect(packet.argv).to be_a RubySMB::Dcerpc::Ndr::NdrConfArray
27
+ expect(packet.argv[0]).to be_a RubySMB::Dcerpc::Ndr::NdrWideStringPtr
28
+ end
29
+ end
30
+
31
+ describe '#initialize_instance' do
32
+ it 'sets #opnum to START_SERVICE_W constant' do
33
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Svcctl::START_SERVICE_W)
34
+ end
35
+ end
36
+
37
+ it 'reads its own binary representation and outputs the same packet' do
38
+ packet = described_class.new(
39
+ h_service: {context_handle_attributes: 0, context_handle_uuid: '367abb81-9844-35f1-ad32-98f038001003'},
40
+ argc: 3,
41
+ argv: ['test', '-c', '-e']
42
+ )
43
+ binary = packet.to_binary_s
44
+ expect(described_class.read(binary)).to eq(packet)
45
+ end
46
+ end
47
+
@@ -0,0 +1,30 @@
1
+ RSpec.describe RubySMB::Dcerpc::Svcctl::StartServiceWResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :error_status }
5
+
6
+ it 'is little endian' do
7
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
8
+ end
9
+
10
+ describe '#error_status' do
11
+ it 'is a NdrUint32' do
12
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
13
+ end
14
+ end
15
+
16
+ describe '#initialize_instance' do
17
+ it 'sets #opnum to START_SERVICE_W constant' do
18
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Svcctl::START_SERVICE_W)
19
+ end
20
+ end
21
+
22
+ it 'reads its own binary representation and outputs the same packet' do
23
+ packet = described_class.new(
24
+ error_status: 3
25
+ )
26
+ binary = packet.to_binary_s
27
+ expect(described_class.read(binary)).to eq(packet)
28
+ end
29
+ end
30
+
@@ -0,0 +1,508 @@
1
+ RSpec.describe RubySMB::Dcerpc::Svcctl do
2
+ let(:svcctl) do
3
+ RubySMB::SMB1::Pipe.new(
4
+ tree: double('Tree'),
5
+ response: RubySMB::SMB1::Packet::NtCreateAndxResponse.new,
6
+ name: 'svcctl'
7
+ )
8
+ end
9
+
10
+ describe '#open_sc_manager_w' do
11
+ let(:rhost) { '1.2.3.4' }
12
+ let(:open_sc_manager_w_request) { double('OpenSCManagerW Request Packet') }
13
+ let(:response) { double('Response') }
14
+ let(:open_sc_manager_w_response) { double('OpenSCManagerW Response Packet') }
15
+ let(:lp_sc_handle) { double('LpScHandle') }
16
+ before :example do
17
+ allow(described_class::OpenSCManagerWRequest).to receive(:new).and_return(open_sc_manager_w_request)
18
+ allow(open_sc_manager_w_request).to receive_messages(
19
+ :lp_machine_name= => nil,
20
+ :lp_database_name= => nil,
21
+ )
22
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
23
+ allow(described_class::OpenSCManagerWResponse).to receive(:read).and_return(open_sc_manager_w_response)
24
+ allow(open_sc_manager_w_response).to receive_messages(
25
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
26
+ :lp_sc_handle => lp_sc_handle
27
+ )
28
+ end
29
+
30
+ it 'create the expected OpenSCManagerWRequest packet with the default desired access' do
31
+ access =
32
+ described_class::SERVICE_START |
33
+ described_class::SERVICE_STOP |
34
+ described_class::SERVICE_CHANGE_CONFIG |
35
+ described_class::SERVICE_QUERY_CONFIG |
36
+ described_class::SERVICE_QUERY_STATUS |
37
+ described_class::SERVICE_ENUMERATE_DEPENDENTS |
38
+ described_class::SC_MANAGER_ENUMERATE_SERVICE
39
+ svcctl.open_sc_manager_w(rhost)
40
+ expect(described_class::OpenSCManagerWRequest).to have_received(:new).with(dw_desired_access: access)
41
+ end
42
+
43
+ it 'create the expected OpenSCManagerWRequest packet with custom desired access' do
44
+ access =
45
+ described_class::SERVICE_QUERY_CONFIG |
46
+ described_class::SERVICE_ENUMERATE_DEPENDENTS |
47
+ described_class::SC_MANAGER_ENUMERATE_SERVICE
48
+ svcctl.open_sc_manager_w(rhost, access)
49
+ expect(described_class::OpenSCManagerWRequest).to have_received(:new).with(dw_desired_access: access)
50
+ end
51
+
52
+ it 'sets the expected fields on the request packet' do
53
+ svcctl.open_sc_manager_w(rhost)
54
+ expect(open_sc_manager_w_request).to have_received(:lp_machine_name=).with(rhost)
55
+ expect(open_sc_manager_w_request).to have_received(:lp_database_name=).with('ServicesActive')
56
+ end
57
+
58
+ it 'sends the expected dcerpc request' do
59
+ svcctl.open_sc_manager_w(rhost)
60
+ expect(svcctl).to have_received(:dcerpc_request).with(open_sc_manager_w_request)
61
+ end
62
+
63
+ it 'creates a OpenSCManagerWResponse structure from the expected dcerpc response' do
64
+ svcctl.open_sc_manager_w(rhost)
65
+ expect(described_class::OpenSCManagerWResponse).to have_received(:read).with(response)
66
+ end
67
+
68
+ context 'when an IOError occurs while parsing the response' do
69
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
70
+ allow(described_class::OpenSCManagerWResponse).to receive(:read).and_raise(IOError)
71
+ expect { svcctl.open_sc_manager_w(rhost) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
72
+ end
73
+ end
74
+
75
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
76
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
77
+ allow(open_sc_manager_w_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
78
+ expect { svcctl.open_sc_manager_w(rhost) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
79
+ end
80
+ end
81
+
82
+ it 'returns the expected handler' do
83
+ expect(svcctl.open_sc_manager_w(rhost)).to eq(lp_sc_handle)
84
+ end
85
+ end
86
+
87
+ describe '#open_service_w' do
88
+ let(:scm_handle) { '1.2.3.4' }
89
+ let(:service_name) { 'MyService' }
90
+ let(:open_service_w_request) { double('OpenServiceW Request Packet') }
91
+ let(:response) { double('Response') }
92
+ let(:open_service_w_response) { double('OpenServiceW Response Packet') }
93
+ let(:lp_sc_handle) { double('LpScHandle') }
94
+ before :example do
95
+ allow(described_class::OpenServiceWRequest).to receive(:new).and_return(open_service_w_request)
96
+ allow(open_service_w_request).to receive_messages(
97
+ :lp_sc_handle= => nil,
98
+ :lp_service_name= => nil,
99
+ )
100
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
101
+ allow(described_class::OpenServiceWResponse).to receive(:read).and_return(open_service_w_response)
102
+ allow(open_service_w_response).to receive_messages(
103
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
104
+ :lp_sc_handle => lp_sc_handle
105
+ )
106
+ end
107
+
108
+ it 'create the expected OpenServiceWRequest packet with the default desired access' do
109
+ access = described_class::SERVICE_ALL_ACCESS
110
+ svcctl.open_service_w(scm_handle, service_name)
111
+ expect(described_class::OpenServiceWRequest).to have_received(:new).with(dw_desired_access: access)
112
+ end
113
+
114
+ it 'create the expected OpenServiceWRequest packet with custom desired access' do
115
+ access =
116
+ described_class::SERVICE_QUERY_CONFIG |
117
+ described_class::SERVICE_ENUMERATE_DEPENDENTS |
118
+ described_class::SC_MANAGER_ENUMERATE_SERVICE
119
+ svcctl.open_service_w(scm_handle, service_name, access)
120
+ expect(described_class::OpenServiceWRequest).to have_received(:new).with(dw_desired_access: access)
121
+ end
122
+
123
+ it 'sets the expected fields on the request packet' do
124
+ svcctl.open_service_w(scm_handle, service_name)
125
+ expect(open_service_w_request).to have_received(:lp_sc_handle=).with(scm_handle)
126
+ expect(open_service_w_request).to have_received(:lp_service_name=).with(service_name)
127
+ end
128
+
129
+ it 'sends the expected dcerpc request' do
130
+ svcctl.open_service_w(scm_handle, service_name)
131
+ expect(svcctl).to have_received(:dcerpc_request).with(open_service_w_request)
132
+ end
133
+
134
+ it 'creates a OpenServiceWResponse structure from the expected dcerpc response' do
135
+ svcctl.open_service_w(scm_handle, service_name)
136
+ expect(described_class::OpenServiceWResponse).to have_received(:read).with(response)
137
+ end
138
+
139
+ context 'when an IOError occurs while parsing the response' do
140
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
141
+ allow(described_class::OpenServiceWResponse).to receive(:read).and_raise(IOError)
142
+ expect { svcctl.open_service_w(scm_handle, service_name) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
143
+ end
144
+ end
145
+
146
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
147
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
148
+ allow(open_service_w_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
149
+ expect { svcctl.open_service_w(scm_handle, service_name) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
150
+ end
151
+ end
152
+
153
+ it 'returns the expected handler' do
154
+ expect(svcctl.open_service_w(scm_handle, service_name)).to eq(lp_sc_handle)
155
+ end
156
+ end
157
+
158
+ describe '#query_service_status' do
159
+ let(:svc_handle) { double('Service Handle') }
160
+ let(:query_service_status_request) { double('QueryServiceStatus Request Packet') }
161
+ let(:response) { double('Response') }
162
+ let(:query_service_status_response) { double('QueryServiceStatus Response Packet') }
163
+ let(:lp_service_status) { double('LpServiceStatus') }
164
+ before :example do
165
+ allow(described_class::QueryServiceStatusRequest).to receive(:new).and_return(query_service_status_request)
166
+ allow(query_service_status_request).to receive_messages(
167
+ :h_service= => nil,
168
+ )
169
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
170
+ allow(described_class::QueryServiceStatusResponse).to receive(:read).and_return(query_service_status_response)
171
+ allow(query_service_status_response).to receive_messages(
172
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
173
+ :lp_service_status => lp_service_status
174
+ )
175
+ end
176
+
177
+ it 'create the expected QueryServiceStatusRequest packet' do
178
+ svcctl.query_service_status(svc_handle)
179
+ expect(described_class::QueryServiceStatusRequest).to have_received(:new)
180
+ end
181
+
182
+ it 'sets the expected fields on the request packet' do
183
+ svcctl.query_service_status(svc_handle)
184
+ expect(query_service_status_request).to have_received(:h_service=).with(svc_handle)
185
+ end
186
+
187
+ it 'sends the expected dcerpc request' do
188
+ svcctl.query_service_status(svc_handle)
189
+ expect(svcctl).to have_received(:dcerpc_request).with(query_service_status_request)
190
+ end
191
+
192
+ it 'creates a QueryServiceStatusResponse structure from the expected dcerpc response' do
193
+ svcctl.query_service_status(svc_handle)
194
+ expect(described_class::QueryServiceStatusResponse).to have_received(:read).with(response)
195
+ end
196
+
197
+ context 'when an IOError occurs while parsing the response' do
198
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
199
+ allow(described_class::QueryServiceStatusResponse).to receive(:read).and_raise(IOError)
200
+ expect { svcctl.query_service_status(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
201
+ end
202
+ end
203
+
204
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
205
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
206
+ allow(query_service_status_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
207
+ expect { svcctl.query_service_status(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
208
+ end
209
+ end
210
+
211
+ it 'returns the expected handler' do
212
+ expect(svcctl.query_service_status(svc_handle)).to eq(lp_service_status)
213
+ end
214
+ end
215
+
216
+ describe '#query_service_config' do
217
+ let(:svc_handle) { double('Service Handle') }
218
+ let(:query_service_config_request) { double('QueryServiceConfigW Request Packet') }
219
+ let(:response) { double('Response') }
220
+ let(:query_service_config_response) { double('QueryServiceConfigW Response Packet') }
221
+ let(:lp_service_config) { double('LpServiceConfig') }
222
+ before :example do
223
+ allow(described_class::QueryServiceConfigWRequest).to receive(:new).and_return(query_service_config_request)
224
+ allow(query_service_config_request).to receive_messages(
225
+ :h_service= => nil,
226
+ :cb_buf_size= => nil,
227
+ )
228
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
229
+ allow(described_class::QueryServiceConfigWResponse).to receive(:read).and_return(query_service_config_response)
230
+ allow(query_service_config_response).to receive_messages(
231
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
232
+ :lp_service_config => lp_service_config
233
+ )
234
+ end
235
+
236
+ it 'create the expected QueryServiceConfigWRequest packet' do
237
+ svcctl.query_service_config(svc_handle)
238
+ expect(described_class::QueryServiceConfigWRequest).to have_received(:new)
239
+ end
240
+
241
+ it 'sets the expected fields on the request packet' do
242
+ svcctl.query_service_config(svc_handle)
243
+ expect(query_service_config_request).to have_received(:h_service=).with(svc_handle)
244
+ expect(query_service_config_request).to have_received(:cb_buf_size=).with(0)
245
+ end
246
+
247
+ it 'sends the expected dcerpc request' do
248
+ svcctl.query_service_config(svc_handle)
249
+ expect(svcctl).to have_received(:dcerpc_request).with(query_service_config_request)
250
+ end
251
+
252
+ it 'creates a QueryServiceConfigWResponse structure from the expected dcerpc response' do
253
+ svcctl.query_service_config(svc_handle)
254
+ expect(described_class::QueryServiceConfigWResponse).to have_received(:read).with(response)
255
+ end
256
+
257
+ context 'when an IOError occurs while parsing the response' do
258
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
259
+ allow(described_class::QueryServiceConfigWResponse).to receive(:read).and_raise(IOError)
260
+ expect { svcctl.query_service_config(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
261
+ end
262
+ end
263
+
264
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
265
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
266
+ allow(query_service_config_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
267
+ expect { svcctl.query_service_config(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
268
+ end
269
+ end
270
+
271
+ it 'returns the expected handler' do
272
+ expect(svcctl.query_service_config(svc_handle)).to eq(lp_service_config)
273
+ end
274
+ end
275
+
276
+ describe '#change_service_config_w' do
277
+ let(:svc_handle) { double('Service Handle') }
278
+ let(:change_service_config_w_request) { double('ChangeServiceConfigW Request Packet') }
279
+ let(:response) { double('Response') }
280
+ let(:change_service_config_w_response) { double('ChangeServiceConfigW Response Packet') }
281
+ before :example do
282
+ allow(described_class::ChangeServiceConfigWRequest).to receive(:new).and_return(change_service_config_w_request)
283
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
284
+ allow(described_class::ChangeServiceConfigWResponse).to receive(:read).and_return(change_service_config_w_response)
285
+ allow(change_service_config_w_response).to receive_messages(
286
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
287
+ )
288
+ end
289
+
290
+ it 'create the expected ChangeServiceConfigWRequest packet with the default options' do
291
+ opts = {
292
+ h_service: svc_handle,
293
+ dw_service_type: described_class::SERVICE_NO_CHANGE,
294
+ dw_start_type: described_class::SERVICE_NO_CHANGE,
295
+ dw_error_control: described_class::SERVICE_NO_CHANGE,
296
+ lp_binary_path_name: :null,
297
+ lp_load_order_group: :null,
298
+ dw_tag_id: :null,
299
+ lp_dependencies: [],
300
+ lp_service_start_name: :null,
301
+ lp_password: [],
302
+ lp_display_name: :null
303
+ }
304
+ svcctl.change_service_config_w(svc_handle)
305
+ expect(described_class::ChangeServiceConfigWRequest).to have_received(:new).with(opts)
306
+ end
307
+
308
+ it 'create the expected ChangeServiceConfigWRequest packet with custom options' do
309
+ opts = {
310
+ service: svc_handle,
311
+ service_type: described_class::SERVICE_KERNEL_DRIVER,
312
+ start_type: described_class::SERVICE_SYSTEM_START,
313
+ error_control: described_class::SERVICE_ERROR_SEVERE,
314
+ binary_path_name: '\\path\\to\\binary',
315
+ load_order_group: 'load order',
316
+ tag_id: 2,
317
+ dependencies: [1, 2, 3],
318
+ service_start_name: 'My service',
319
+ password: [1, 2, 3],
320
+ display_name: 'Name'
321
+ }
322
+ opts2 = {
323
+ h_service: svc_handle,
324
+ dw_service_type: opts[:service_type],
325
+ dw_start_type: opts[:start_type],
326
+ dw_error_control: opts[:error_control],
327
+ lp_binary_path_name: opts[:binary_path_name],
328
+ lp_load_order_group: opts[:load_order_group],
329
+ dw_tag_id: opts[:tag_id],
330
+ lp_dependencies: opts[:dependencies],
331
+ lp_service_start_name: opts[:service_start_name],
332
+ lp_password: opts[:password],
333
+ lp_display_name: opts[:display_name]
334
+ }
335
+ svcctl.change_service_config_w(svc_handle, opts)
336
+ expect(described_class::ChangeServiceConfigWRequest).to have_received(:new).with(opts2)
337
+ end
338
+
339
+ it 'sends the expected dcerpc request' do
340
+ svcctl.change_service_config_w(svc_handle)
341
+ expect(svcctl).to have_received(:dcerpc_request).with(change_service_config_w_request)
342
+ end
343
+
344
+ it 'creates a ChangeServiceConfigWResponse structure from the expected dcerpc response' do
345
+ svcctl.change_service_config_w(svc_handle)
346
+ expect(described_class::ChangeServiceConfigWResponse).to have_received(:read).with(response)
347
+ end
348
+
349
+ context 'when an IOError occurs while parsing the response' do
350
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
351
+ allow(described_class::ChangeServiceConfigWResponse).to receive(:read).and_raise(IOError)
352
+ expect { svcctl.change_service_config_w(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
353
+ end
354
+ end
355
+
356
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
357
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
358
+ allow(change_service_config_w_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
359
+ expect { svcctl.change_service_config_w(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
360
+ end
361
+ end
362
+ end
363
+
364
+ describe '#start_service_w' do
365
+ let(:svc_handle) { double('Service Handle') }
366
+ let(:start_service_w_request) { double('StartServiceW Request Packet') }
367
+ let(:response) { double('Response') }
368
+ let(:start_service_w_response) { double('StartServiceW Response Packet') }
369
+ before :example do
370
+ allow(described_class::StartServiceWRequest).to receive(:new).and_return(start_service_w_request)
371
+ allow(start_service_w_request).to receive_messages(
372
+ :h_service= => nil,
373
+ :argc= => nil,
374
+ :argv= => nil,
375
+ )
376
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
377
+ allow(described_class::StartServiceWResponse).to receive(:read).and_return(start_service_w_response)
378
+ allow(start_service_w_response).to receive_messages(
379
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
380
+ )
381
+ end
382
+
383
+ it 'create the expected StartServiceWRequest packet' do
384
+ svcctl.start_service_w(svc_handle)
385
+ expect(described_class::StartServiceWRequest).to have_received(:new)
386
+ end
387
+
388
+ it 'sets the provided Service start arguments' do
389
+ argv = ['my', 'arguments', 'to', 'test']
390
+ svcctl.start_service_w(svc_handle, argv)
391
+ expect(start_service_w_request).to have_received(:argc=).with(argv.size)
392
+ expect(start_service_w_request).to have_received(:argv=).with(argv)
393
+ end
394
+
395
+ it 'sends the expected dcerpc request' do
396
+ svcctl.start_service_w(svc_handle)
397
+ expect(svcctl).to have_received(:dcerpc_request).with(start_service_w_request)
398
+ end
399
+
400
+ it 'creates a StartServiceWResponse structure from the expected dcerpc response' do
401
+ svcctl.start_service_w(svc_handle)
402
+ expect(described_class::StartServiceWResponse).to have_received(:read).with(response)
403
+ end
404
+
405
+ context 'when an IOError occurs while parsing the response' do
406
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
407
+ allow(described_class::StartServiceWResponse).to receive(:read).and_raise(IOError)
408
+ expect { svcctl.start_service_w(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
409
+ end
410
+ end
411
+
412
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
413
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
414
+ allow(start_service_w_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
415
+ expect { svcctl.start_service_w(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
416
+ end
417
+ end
418
+ end
419
+
420
+ describe '#control_service' do
421
+ let(:svc_handle) { double('Service Handle') }
422
+ let(:control) { double('Control') }
423
+ let(:control_service_request) { double('ControlService Request Packet') }
424
+ let(:response) { double('Response') }
425
+ let(:control_service_response) { double('ControlService Response Packet') }
426
+ before :example do
427
+ allow(described_class::ControlServiceRequest).to receive(:new).and_return(control_service_request)
428
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
429
+ allow(described_class::ControlServiceResponse).to receive(:read).and_return(control_service_response)
430
+ allow(control_service_response).to receive_messages(
431
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
432
+ )
433
+ end
434
+
435
+ it 'create the expected ControlServiceRequest packet' do
436
+ svcctl.control_service(svc_handle, control)
437
+ expect(described_class::ControlServiceRequest).to have_received(:new).with(h_service: svc_handle, dw_control: control)
438
+ end
439
+
440
+ it 'sends the expected dcerpc request' do
441
+ svcctl.control_service(svc_handle, control)
442
+ expect(svcctl).to have_received(:dcerpc_request).with(control_service_request)
443
+ end
444
+
445
+ it 'creates a ControlServiceResponse structure from the expected dcerpc response' do
446
+ svcctl.control_service(svc_handle, control)
447
+ expect(described_class::ControlServiceResponse).to have_received(:read).with(response)
448
+ end
449
+
450
+ context 'when an IOError occurs while parsing the response' do
451
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
452
+ allow(described_class::ControlServiceResponse).to receive(:read).and_raise(IOError)
453
+ expect { svcctl.control_service(svc_handle, control) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
454
+ end
455
+ end
456
+
457
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
458
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
459
+ allow(control_service_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
460
+ expect { svcctl.control_service(svc_handle, control) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
461
+ end
462
+ end
463
+ end
464
+
465
+ describe '#close_service_handle' do
466
+ let(:svc_handle) { double('Service Handle') }
467
+ let(:close_service_handle_request) { double('CloseServiceHandle Request Packet') }
468
+ let(:response) { double('Response') }
469
+ let(:close_service_handle_response) { double('CloseServiceHandle Response Packet') }
470
+ before :example do
471
+ allow(described_class::CloseServiceHandleRequest).to receive(:new).and_return(close_service_handle_request)
472
+ allow(svcctl).to receive(:dcerpc_request).and_return(response)
473
+ allow(described_class::CloseServiceHandleResponse).to receive(:read).and_return(close_service_handle_response)
474
+ allow(close_service_handle_response).to receive_messages(
475
+ :error_status => WindowsError::Win32::ERROR_SUCCESS,
476
+ )
477
+ end
478
+
479
+ it 'create the expected CloseServiceHandleRequest packet' do
480
+ svcctl.close_service_handle(svc_handle)
481
+ expect(described_class::CloseServiceHandleRequest).to have_received(:new).with(h_sc_object: svc_handle)
482
+ end
483
+
484
+ it 'sends the expected dcerpc request' do
485
+ svcctl.close_service_handle(svc_handle)
486
+ expect(svcctl).to have_received(:dcerpc_request).with(close_service_handle_request)
487
+ end
488
+
489
+ it 'creates a CloseServiceHandleResponse structure from the expected dcerpc response' do
490
+ svcctl.close_service_handle(svc_handle)
491
+ expect(described_class::CloseServiceHandleResponse).to have_received(:read).with(response)
492
+ end
493
+
494
+ context 'when an IOError occurs while parsing the response' do
495
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
496
+ allow(described_class::CloseServiceHandleResponse).to receive(:read).and_raise(IOError)
497
+ expect { svcctl.close_service_handle(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
498
+ end
499
+ end
500
+
501
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
502
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
503
+ allow(close_service_handle_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
504
+ expect { svcctl.close_service_handle(svc_handle) }.to raise_error(RubySMB::Dcerpc::Error::SvcctlError)
505
+ end
506
+ end
507
+ end
508
+ end
@@ -12,6 +12,10 @@ RSpec.describe RubySMB::Dcerpc::Uuid do
12
12
  expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
13
13
  end
14
14
 
15
+ it 'is 4-byte aligned' do
16
+ expect(packet.eval_parameter(:byte_align)).to eq(4)
17
+ end
18
+
15
19
  describe '#time_low' do
16
20
  it 'should be a 32-bit unsigned integer' do
17
21
  expect(packet.time_low).to be_a BinData::Uint32le
@@ -78,31 +82,19 @@ RSpec.describe RubySMB::Dcerpc::Uuid do
78
82
  expect(packet.clock_seq_low).to eq 0xE8
79
83
  expect(packet.node).to eq [0x08, 0x00, 0x2B, 0x10, 0x48, 0x60]
80
84
  end
85
+
86
+ it 'removes surrounding curly brackets' do
87
+ packet.set("{#{uuid_string}}")
88
+ expect(packet).to eq(uuid_string)
89
+ end
81
90
  end
82
91
  end
83
92
 
84
- end
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
- RSpec.describe RubySMB::Dcerpc::Uuid do
100
- let(:uuid_string){'8a885d04-1ceb-11c9-9fe8-08002b104860'}
101
- let(:uuid){RubySMB::Dcerpc::Uuid.new(initial_value: uuid_string)}
102
-
103
- describe '#initialize' do
104
- it 'should create a 16 byte struct' do
105
- expect(uuid.do_num_bytes).to be 16
106
- end
93
+ it 'reads its own binary representation and output the same packet' do
94
+ packet = described_class.new('8a885d04-1ceb-11c9-9fe8-08002b104860')
95
+ binary = packet.to_binary_s
96
+ expect(described_class.read(binary)).to eq(packet)
107
97
  end
98
+
108
99
  end
100
+
@@ -22,8 +22,8 @@ RSpec.describe RubySMB::Dcerpc::Winreg::CloseKeyResponse do
22
22
  end
23
23
 
24
24
  describe '#error_status' do
25
- it 'is a 32-bit unsigned integer' do
26
- expect(packet.error_status).to be_a BinData::Uint32le
25
+ it 'is a NdrUint32' do
26
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
27
27
  end
28
28
  end
29
29