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,477 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Svcctl
4
+
5
+ UUID = '367abb81-9844-35f1-ad32-98f038001003'
6
+ VER_MAJOR = 2
7
+ VER_MINOR = 0
8
+
9
+ # Operation numbers
10
+ CLOSE_SERVICE_HANDLE = 0x0000
11
+ CONTROL_SERVICE = 0x0001
12
+ QUERY_SERVICE_STATUS = 0x0006
13
+ CHANGE_SERVICE_CONFIG_W = 0x000B
14
+ OPEN_SC_MANAGER_W = 0x000F
15
+ OPEN_SERVICE_W = 0x0010
16
+ QUERY_SERVICE_CONFIG_W = 0x0011
17
+ START_SERVICE_W = 0x0013
18
+
19
+
20
+ class ScRpcHandle < Ndr::NdrContextHandle; end
21
+
22
+
23
+ #################################
24
+ # Constants #
25
+ #################################
26
+
27
+
28
+ ################
29
+ # Service Access
30
+ # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-scmr/0d7a7011-9f41-470d-ad52-8535b47ac282
31
+
32
+ # In addition to all access rights in this table, SERVICE_ALL_ACCESS
33
+ # includes Delete (DE), Read Control (RC), Write DACL (WD), and Write
34
+ # Owner (WO) access, as specified in ACCESS_MASK (section 2.4.3) of
35
+ # [MS-DTYP].
36
+ SERVICE_ALL_ACCESS = 0x000F01FF
37
+ # Required to change the configuration of a service.
38
+ SERVICE_CHANGE_CONFIG = 0x00000002
39
+ # Required to enumerate the services installed on the server.
40
+ SERVICE_ENUMERATE_DEPENDENTS = 0x00000008
41
+ # Required to request immediate status from the service.
42
+ SERVICE_INTERROGATE = 0x00000080
43
+ # Required to pause or continue the service.
44
+ SERVICE_PAUSE_CONTINUE = 0x00000040
45
+ # Required to query the service configuration.
46
+ SERVICE_QUERY_CONFIG = 0x00000001
47
+ # Required to request the service status.
48
+ SERVICE_QUERY_STATUS = 0x00000004
49
+ # Required to start the service.
50
+ SERVICE_START = 0x00000010
51
+ # Required to stop the service.
52
+ SERVICE_STOP = 0x00000020
53
+ # Required to specify a user-defined control code.
54
+ SERVICE_USER_DEFINED_CONTROL = 0x00000100
55
+ # Required for a service to set its status.
56
+ SERVICE_SET_STATUS = 0x00008000
57
+
58
+ # Specific access types for Service Control Manager object:
59
+
60
+ # Required to lock the SCM database.
61
+ SC_MANAGER_LOCK = 0x00000008
62
+ # Required for a service to be created.
63
+ SC_MANAGER_CREATE_SERVICE = 0x00000002
64
+ # Required to enumerate a service.
65
+ SC_MANAGER_ENUMERATE_SERVICE = 0x00000004
66
+ # Required to connect to the SCM.
67
+ SC_MANAGER_CONNECT = 0x00000001
68
+ # Required to query the lock status of the SCM database.
69
+ SC_MANAGER_QUERY_LOCK_STATUS = 0x00000010
70
+ # Required to call the RNotifyBootConfigStatus method.
71
+ SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00000020
72
+
73
+
74
+ ##############
75
+ # Service Type
76
+
77
+ # A driver service. These are services that manage devices on the system.
78
+ SERVICE_KERNEL_DRIVER = 0x00000001
79
+ # A file system driver service. These are services that manage file
80
+ # systems on the system.
81
+ SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
82
+ # A service that runs in its own process.
83
+ SERVICE_WIN32_OWN_PROCESS = 0x00000010
84
+ # A service that shares a process with other services.
85
+ SERVICE_WIN32_SHARE_PROCESS = 0x00000020
86
+
87
+ # The service can interact with the desktop. Only
88
+ # SERVICE_WIN32_OWN_PROCESS and SERVICE_INTERACTIVE_PROCESS OR
89
+ # SERVICE_WIN32_SHARE_PROCESS and SERVICE_INTERACTIVE_PROCESS can be
90
+ # combined.
91
+ SERVICE_INTERACTIVE_PROCESS = 0x00000100
92
+
93
+ ####################
94
+ # Service Start Type
95
+
96
+ # Starts the driver service when the system boots up. This value is valid
97
+ # only for driver services.
98
+ SERVICE_BOOT_START = 0x00000000
99
+ # Starts the driver service when the system boots up. This value is valid
100
+ # only for driver services. The services marked SERVICE_SYSTEM_START are
101
+ # started after all SERVICE_BOOT_START services have been started.
102
+ SERVICE_SYSTEM_START = 0x00000001
103
+ # A service started automatically by the SCM during system startup.
104
+ SERVICE_AUTO_START = 0x00000002
105
+ # Starts the service when a client requests the SCM to start the service.
106
+ SERVICE_DEMAND_START = 0x00000003
107
+ # A service that cannot be started. Attempts to start the service result
108
+ # in the error code ERROR_SERVICE_DISABLED.
109
+ SERVICE_DISABLED = 0x00000004
110
+
111
+
112
+ #######################
113
+ # Service Error Control
114
+
115
+ # The severity of the error if this service fails to start during startup
116
+ # and the action the SCM takes if failure occurs.
117
+
118
+ # The SCM ignores the error and continues the startup operation.
119
+ SERVICE_ERROR_IGNORE = 0x00000000
120
+ # The SCM logs the error in the event log and continues the startup
121
+ # operation.
122
+ SERVICE_ERROR_NORMAL = 0x00000001
123
+ # The SCM logs the error in the event log. If the last-known good
124
+ # configuration is being started, the startup operation continues.
125
+ # Otherwise, the system is restarted with the last-known good
126
+ # configuration.
127
+ SERVICE_ERROR_SEVERE = 0x00000002
128
+ # The SCM SHOULD log the error in the event log if possible. If the
129
+ # last-known good configuration is being started, the startup operation
130
+ # fails. Otherwise, the system is restarted with the last-known good
131
+ # configuration.
132
+ SERVICE_ERROR_CRITICAL = 0x00000003
133
+
134
+
135
+ #########################################
136
+ # Change Service Config specific constant
137
+
138
+ # Service type, start or error control does not change.
139
+ SERVICE_NO_CHANGE = 0xFFFFFFFF
140
+
141
+
142
+ ################
143
+ # Current State
144
+
145
+ SERVICE_PAUSED = 0x00000007
146
+ SERVICE_PAUSE_PENDING = 0x00000006
147
+ SERVICE_CONTINUE_PENDING = 0x00000005
148
+ SERVICE_RUNNING = 0x00000004
149
+ SERVICE_STOP_PENDING = 0x00000003
150
+ SERVICE_START_PENDING = 0x00000002
151
+ SERVICE_STOPPED = 0x00000001
152
+
153
+ ###################
154
+ # Controls Accepted
155
+
156
+ # The control codes that the service accepts and processes in its handler
157
+ # function. One or more of the following values can be set. By default,
158
+ # all services accept the SERVICE_CONTROL_INTERROGATE value. A value of
159
+ # zero indicates that no controls are accepted.
160
+
161
+ # Service can reread its startup parameters without being stopped and
162
+ # restarted. This control code allows the service to receive
163
+ # SERVICE_CONTROL_PARAMCHANGE notifications.
164
+ SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
165
+ # Service can be paused and continued. This control code allows the
166
+ # service to receive SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE
167
+ # notifications.
168
+ SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
169
+ # Service is notified when system shutdown occurs. This control code
170
+ # enables the service to receive SERVICE_CONTROL_SHUTDOWN notifications
171
+ # from the server.
172
+ SERVICE_ACCEPT_SHUTDOWN = 0x00000004
173
+ # Service can be stopped. This control code allows the service to receive
174
+ # SERVICE_CONTROL_STOP notifications.
175
+ SERVICE_ACCEPT_STOP = 0x00000001
176
+ # Service is notified when the computer's hardware profile changes.
177
+ SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
178
+ # Service is notified when the computer's power status changes.
179
+ SERVICE_ACCEPT_POWEREVENT = 0x00000040
180
+ # Service is notified when the computer's session status changes.
181
+ SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
182
+ # The service can perform preshutdown tasks. SERVICE_ACCEPT_PRESHUTDOWN
183
+ # is sent before sending SERVICE_CONTROL_SHUTDOWN to give more time to
184
+ # services that need extra time before shutdown occurs.
185
+ SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
186
+ # Service is notified when the system time changes.
187
+ SERVICE_ACCEPT_TIMECHANGE = 0x00000200
188
+ # Service is notified when an event for which the service has registered
189
+ # occurs.
190
+ SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400
191
+
192
+ ###################
193
+ # Controls
194
+
195
+ # Notifies a paused service that it SHOULD resume. The
196
+ # SERVICE_PAUSE_CONTINUE access right MUST have been granted to the caller
197
+ # when the RPC control handle to the service record was created. The
198
+ # service record MUST have the SERVICE_ACCEPT_PAUSE_CONTINUE bit set in
199
+ # the ServiceStatus.dwControlsAccepted field of the service record.
200
+ SERVICE_CONTROL_CONTINUE = 0x00000003
201
+ # Notifies a service that it SHOULD report its current status information
202
+ # to the SCM. The SERVICE_INTERROGATE access right MUST have been granted
203
+ # to the caller when the RPC control handle to the service record was
204
+ # created.
205
+ SERVICE_CONTROL_INTERROGATE = 0x00000004
206
+ # Notifies a service that there is a new component for binding. The
207
+ # SERVICE_PAUSE_CONTINUE access right MUST have been granted to the
208
+ # caller when the RPC control handle to the service record was created.
209
+ # The service record MUST have the SERVICE_ACCEPT_NETBINDCHANGE bit set
210
+ # in the ServiceStatus.dwControlsAccepted field of the service record.
211
+ SERVICE_CONTROL_NETBINDADD = 0x00000007
212
+ # Notifies a network service that one of its bindings has been disabled.
213
+ # The SERVICE_PAUSE_CONTINUE access right MUST have been granted to the
214
+ # caller when the RPC control handle to the service record was created.
215
+ # The service record MUST have the SERVICE_ACCEPT_NETBINDCHANGE bit set
216
+ # in the ServiceStatus.dwControlsAccepted field of the service record.
217
+ SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
218
+ # Notifies a network service that a disabled binding has been enabled.
219
+ # The SERVICE_PAUSE_CONTINUE access right MUST have been granted to the
220
+ # caller when the RPC control handle to the service record was created.
221
+ # The service record MUST have the SERVICE_ACCEPT_NETBINDCHANGE bit set
222
+ # in the ServiceStatus.dwControlsAccepted field of the service record.
223
+ SERVICE_CONTROL_NETBINDENABLE = 0x00000009
224
+ # Notifies a network service that a component for binding has been
225
+ # removed. The SERVICE_PAUSE_CONTINUE access right MUST have been granted
226
+ # to the caller when the RPC control handle to the service record was
227
+ # created. The service record MUST have the SERVICE_ACCEPT_NETBINDCHANGE
228
+ # bit set in the ServiceStatus.dwControlsAccepted field of the service
229
+ # record.
230
+ SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
231
+ # Notifies a service that its startup parameters have changed. The
232
+ # SERVICE_PAUSE_CONTINUE access right MUST have been granted to the
233
+ # caller when the RPC control handle to the service record was created.
234
+ # The service record MUST have the SERVICE_ACCEPT_PARAMCHANGE bit set in
235
+ # the ServiceStatus.dwControlsAccepted field of the service record.
236
+ SERVICE_CONTROL_PARAMCHANGE = 0x00000006
237
+ # Notifies a service that it SHOULD pause. The SERVICE_PAUSE_CONTINUE
238
+ # access right MUST have been granted to the caller when the RPC control
239
+ # handle to the service record was created. The service record MUST have
240
+ # the SERVICE_ACCEPT_PAUSE_CONTINUE bit set in the
241
+ # ServiceStatus.dwControlsAccepted field of the service record.
242
+ SERVICE_CONTROL_PAUSE = 0x00000002
243
+ # Notifies a service that it SHOULD stop. The SERVICE_STOP access right
244
+ # MUST have been granted to the caller when the RPC control handle to the
245
+ # service record was created. The service record MUST have the
246
+ # SERVICE_ACCEPT_STOP bit set in the ServiceStatus.dwControlsAccepted
247
+ # field of the service record.
248
+ SERVICE_CONTROL_STOP = 0x00000001
249
+
250
+ require 'ruby_smb/dcerpc/svcctl/service_status'
251
+ require 'ruby_smb/dcerpc/svcctl/open_sc_manager_w_request'
252
+ require 'ruby_smb/dcerpc/svcctl/open_sc_manager_w_response'
253
+ require 'ruby_smb/dcerpc/svcctl/open_service_w_request'
254
+ require 'ruby_smb/dcerpc/svcctl/open_service_w_response'
255
+ require 'ruby_smb/dcerpc/svcctl/query_service_status_request'
256
+ require 'ruby_smb/dcerpc/svcctl/query_service_status_response'
257
+ require 'ruby_smb/dcerpc/svcctl/query_service_config_w_request'
258
+ require 'ruby_smb/dcerpc/svcctl/query_service_config_w_response'
259
+ require 'ruby_smb/dcerpc/svcctl/change_service_config_w_request'
260
+ require 'ruby_smb/dcerpc/svcctl/change_service_config_w_response'
261
+ require 'ruby_smb/dcerpc/svcctl/start_service_w_request'
262
+ require 'ruby_smb/dcerpc/svcctl/start_service_w_response'
263
+ require 'ruby_smb/dcerpc/svcctl/control_service_request'
264
+ require 'ruby_smb/dcerpc/svcctl/control_service_response'
265
+ require 'ruby_smb/dcerpc/svcctl/close_service_handle_request'
266
+ require 'ruby_smb/dcerpc/svcctl/close_service_handle_response'
267
+
268
+ # Open the SCM database on the specified server.
269
+ #
270
+ # @param rhost [String] the server's machine name
271
+ # @return [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the newly opened SCM database
272
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a OpenSCManagerWResponse packet
273
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
274
+ def open_sc_manager_w(rhost, access = SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SC_MANAGER_ENUMERATE_SERVICE)
275
+ open_sc_manager_w_request = OpenSCManagerWRequest.new(dw_desired_access: access)
276
+ open_sc_manager_w_request.lp_machine_name = rhost
277
+ open_sc_manager_w_request.lp_database_name = 'ServicesActive'
278
+ response = dcerpc_request(open_sc_manager_w_request)
279
+ begin
280
+ open_sc_manager_w_response = OpenSCManagerWResponse.read(response)
281
+ rescue IOError
282
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading OpenSCManagerWResponse'
283
+ end
284
+ unless open_sc_manager_w_response.error_status == WindowsError::Win32::ERROR_SUCCESS
285
+ raise RubySMB::Dcerpc::Error::SvcctlError,
286
+ "Error returned when opening Service Control Manager (SCM): "\
287
+ "#{WindowsError::Win32.find_by_retval(open_sc_manager_w_response.error_status.value).join(',')}"
288
+ end
289
+ open_sc_manager_w_response.lp_sc_handle
290
+ end
291
+
292
+ # Creates an RPC context handle to an existing service record.
293
+ #
294
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the SCM database
295
+ # @param service_name [Srting] the ServiceName of the service record
296
+ # @param access [Integer] access right
297
+ # @return [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the found service record
298
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a OpenServiceWResponse packet
299
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
300
+ def open_service_w(scm_handle, service_name, access = SERVICE_ALL_ACCESS)
301
+ open_service_w_request = OpenServiceWRequest.new(dw_desired_access: access)
302
+ open_service_w_request.lp_sc_handle = scm_handle
303
+ open_service_w_request.lp_service_name = service_name
304
+ response = dcerpc_request(open_service_w_request)
305
+ begin
306
+ open_sercice_w_response = OpenServiceWResponse.read(response)
307
+ rescue IOError
308
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading OpenServiceWResponse'
309
+ end
310
+ unless open_sercice_w_response.error_status == WindowsError::Win32::ERROR_SUCCESS
311
+ raise RubySMB::Dcerpc::Error::SvcctlError,
312
+ "Error returned when opening #{service_name} service: "\
313
+ "#{WindowsError::Win32.find_by_retval(open_sercice_w_response.error_status.value).join(',')}"
314
+ end
315
+ open_sercice_w_response.lp_sc_handle
316
+ end
317
+
318
+ # Returns the current status of the specified service
319
+ #
320
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record
321
+ # @return [RubySMB::Dcerpc::Svcctl::ServiceStatus] structure that contains the status information for the service
322
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a QueryServiceStatusResponse packet
323
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
324
+ def query_service_status(svc_handle)
325
+ qss_request = QueryServiceStatusRequest.new
326
+ qss_request.h_service = svc_handle
327
+ response = dcerpc_request(qss_request)
328
+ begin
329
+ qss_response = QueryServiceStatusResponse.read(response)
330
+ rescue IOError
331
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading QueryServiceStatusResponse'
332
+ end
333
+ unless qss_response.error_status == WindowsError::Win32::ERROR_SUCCESS
334
+ raise RubySMB::Dcerpc::Error::SvcctlError,
335
+ "Error returned when querying service status: "\
336
+ "#{WindowsError::Win32.find_by_retval(qss_response.error_status.value).join(',')}"
337
+ end
338
+ qss_response.lp_service_status
339
+ end
340
+
341
+ # Returns the configuration parameters of the specified service
342
+ #
343
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record
344
+ # @return [RubySMB::Dcerpc::Svcctl::QueryServiceConfigW] structure that contains the configuration parameters for the service
345
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a QueryServiceConfigWResponse packet
346
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
347
+ def query_service_config(svc_handle)
348
+ qsc_request = QueryServiceConfigWRequest.new
349
+ qsc_request.h_service = svc_handle
350
+ qsc_request.cb_buf_size = 0
351
+ response = dcerpc_request(qsc_request)
352
+ begin
353
+ qsc_response = QueryServiceConfigWResponse.read(response)
354
+ rescue IOError
355
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading QueryServiceConfigWResponse'
356
+ end
357
+ if qsc_response.error_status == WindowsError::Win32::ERROR_INSUFFICIENT_BUFFER
358
+ qsc_request.cb_buf_size = qsc_response.pcb_bytes_needed
359
+ response = dcerpc_request(qsc_request)
360
+ begin
361
+ qsc_response = QueryServiceConfigWResponse.read(response)
362
+ rescue IOError
363
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading QueryServiceConfigWResponse'
364
+ end
365
+ end
366
+ unless qsc_response.error_status == WindowsError::Win32::ERROR_SUCCESS
367
+ raise RubySMB::Dcerpc::Error::SvcctlError,
368
+ "Error returned when querying service configuration: "\
369
+ "#{WindowsError::Win32.find_by_retval(qsc_response.error_status.value).join(',')}"
370
+ end
371
+ qsc_response.lp_service_config
372
+ end
373
+
374
+ # Changes a service's configuration parameters in the SCM database
375
+ #
376
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record
377
+ # @param opts [Hash] configuration parameters to change
378
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a ChangeServiceConfigWResponse packet
379
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
380
+ def change_service_config_w(svc_handle, opts = {})
381
+ opts = {
382
+ h_service: svc_handle,
383
+ dw_service_type: opts[:service_type] || SERVICE_NO_CHANGE,
384
+ dw_start_type: opts[:start_type] || SERVICE_NO_CHANGE,
385
+ dw_error_control: opts[:error_control] || SERVICE_NO_CHANGE,
386
+ lp_binary_path_name: opts[:binary_path_name] || :null,
387
+ lp_load_order_group: opts[:load_order_group] || :null,
388
+ dw_tag_id: opts[:tag_id] || :null,
389
+ lp_dependencies: opts[:dependencies] || [],
390
+ lp_service_start_name: opts[:service_start_name] || :null,
391
+ lp_password: opts[:password] || [],
392
+ lp_display_name: opts[:display_name] || :null
393
+ }
394
+
395
+ csc_request = ChangeServiceConfigWRequest.new(opts)
396
+ response = dcerpc_request(csc_request)
397
+ begin
398
+ csc_response = ChangeServiceConfigWResponse.read(response)
399
+ rescue IOError
400
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading ChangeServiceConfigWResponse'
401
+ end
402
+ unless csc_response.error_status == WindowsError::Win32::ERROR_SUCCESS
403
+ raise RubySMB::Dcerpc::Error::SvcctlError,
404
+ "Error returned when changing the service configuration: "\
405
+ "#{WindowsError::Win32.find_by_retval(csc_response.error_status.value).join(',')}"
406
+ end
407
+ end
408
+
409
+ # Starts a specified service
410
+ #
411
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record
412
+ # @param argv [Array<String>] arguments to the service (Array of
413
+ # strings). The first element in argv must be the name of the service.
414
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a StartServiceWResponse packet
415
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
416
+ def start_service_w(svc_handle, argv = [])
417
+ ss_request = StartServiceWRequest.new(h_service: svc_handle)
418
+ unless argv.empty?
419
+ ss_request.argc = argv.size
420
+ ss_request.argv = argv
421
+ end
422
+ response = dcerpc_request(ss_request)
423
+ begin
424
+ ss_response = StartServiceWResponse.read(response)
425
+ rescue IOError
426
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading StartServiceWResponse'
427
+ end
428
+ unless ss_response.error_status == WindowsError::Win32::ERROR_SUCCESS
429
+ raise RubySMB::Dcerpc::Error::SvcctlError,
430
+ "Error returned when starting the service: "\
431
+ "#{WindowsError::Win32.find_by_retval(ss_response.error_status.value).join(',')}"
432
+ end
433
+ end
434
+
435
+ # Send a control code to a specific service handle
436
+ #
437
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record
438
+ # @param control [Integer] control code
439
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a ControlServiceResponse packet
440
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
441
+ def control_service(svc_handle, control)
442
+ cs_request = ControlServiceRequest.new(h_service: svc_handle, dw_control: control)
443
+ response = dcerpc_request(cs_request)
444
+ begin
445
+ cs_response = ControlServiceResponse.read(response)
446
+ rescue IOError
447
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading ControlServiceResponse'
448
+ end
449
+ unless cs_response.error_status == WindowsError::Win32::ERROR_SUCCESS
450
+ raise RubySMB::Dcerpc::Error::SvcctlError,
451
+ "Error returned when sending a control to the service: "\
452
+ "#{WindowsError::Win32.find_by_retval(cs_response.error_status.value).join(',')}"
453
+ end
454
+ end
455
+
456
+ # Releases the handle to the specified service or the SCM database.
457
+ #
458
+ # @param scm_handle [RubySMB::Dcerpc::Svcctl::ScRpcHandle] handle to the service record or to the SCM database
459
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a CloseServiceHandleResponse packet
460
+ # @raise [RubySMB::Dcerpc::Error::SvcctlError] if the response error status is not ERROR_SUCCESS
461
+ def close_service_handle(svc_handle)
462
+ csh_request = CloseServiceHandleRequest.new(h_sc_object: svc_handle)
463
+ response = dcerpc_request(csh_request)
464
+ begin
465
+ csh_response = CloseServiceHandleResponse.read(response)
466
+ rescue IOError
467
+ raise RubySMB::Dcerpc::Error::InvalidPacket, 'Error reading CloseServiceHandleResponse'
468
+ end
469
+ unless csh_response.error_status == WindowsError::Win32::ERROR_SUCCESS
470
+ raise RubySMB::Dcerpc::Error::SvcctlError,
471
+ "Error returned when closing the service: "\
472
+ "#{WindowsError::Win32.find_by_retval(csh_response.error_status.value).join(',')}"
473
+ end
474
+ end
475
+ end
476
+ end
477
+ end
@@ -3,6 +3,7 @@ module RubySMB
3
3
 
4
4
  # [Universal Unique Identifier](http://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm)
5
5
  class Uuid < BinData::Primitive
6
+ default_parameter byte_align: 4
6
7
  endian :little
7
8
  uint32 :time_low, label: 'Low field of the timestamp'
8
9
  uint16 :time_mid, label: 'Middle field of the timestamp'
@@ -21,6 +22,8 @@ module RubySMB
21
22
  end
22
23
 
23
24
  def set(uuid_string)
25
+ uuid_string.delete_suffix!('}')
26
+ uuid_string.delete_prefix!('{')
24
27
  components = uuid_string.split('-')
25
28
  self.time_low.read(to_binary_le(components[0]))
26
29
  self.time_mid.read(to_binary_le(components[1]))
@@ -11,8 +11,8 @@ module RubySMB
11
11
 
12
12
  endian :little
13
13
 
14
- rpc_hkey :hkey
15
- uint32 :error_status
14
+ rpc_hkey :hkey
15
+ ndr_uint32 :error_status
16
16
 
17
17
  def initialize_instance
18
18
  super
@@ -0,0 +1,62 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Winreg
4
+
5
+ class RpcHkey < Ndr::NdrContextHandle; end
6
+
7
+ # This class represents a BaseRegCreateKey Request Packet as defined in
8
+ # [3.1.5.7 BaseRegCreateKey (Opnum 6)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c7186ae2-1c82-45e9-933b-97d9873657e8)
9
+ class CreateKeyRequest < BinData::Record
10
+ # Options:
11
+ # bitwise OR of one of the key types (REG_KEY_TYPE_*), and any or none
12
+ # of the other options:
13
+ #
14
+ # This key is not volatile. The key and all its values MUST be
15
+ # persisted to the backing store and is preserved when the registry
16
+ # server loses context due to a computer restart, reboot, or shut down
17
+ # process.
18
+ REG_KEY_TYPE_NON_VOLATILE = 0x00000000
19
+ # This key is volatile. The key with all its subkeys and values MUST
20
+ # NOT be preserved when the registry server loses context due to a
21
+ # computer restart, reboot, or shut down process.
22
+ REG_KEY_TYPE_VOLATILE = 0x00000001
23
+ # This key is a symbolic link to another key.
24
+ REG_KEY_TYPE_SYMLINK = 0x00000002
25
+ # Indicates that the caller wishes to assert its backup and/or restore
26
+ # privileges.
27
+ REG_OPTION_BACKUP_RESTORE = 0x00000004
28
+ # Indicates that the caller wishes to open the targeted symlink source
29
+ # rather than the symlink target.
30
+ REG_OPTION_OPEN_LINK = 0x00000008
31
+ # Indicates that the caller wishes to disable limited user access
32
+ # virtualization for this operation.
33
+ REG_OPTION_DONT_VIRTUALIZE = 0x00000010
34
+
35
+
36
+ # Create disposition:
37
+ # The key did not exist and was created.
38
+ REG_CREATED_NEW_KEY = 0x00000001
39
+ # The key already existed and was opened without being changed.
40
+ REG_OPENED_EXISTING_KEY = 0x00000002
41
+
42
+ attr_reader :opnum
43
+
44
+ endian :little
45
+
46
+ rpc_hkey :hkey
47
+ rrp_unicode_string :lp_sub_key
48
+ rrp_unicode_string :lp_class
49
+ ndr_uint32 :dw_options
50
+ regsam :sam_desired
51
+ prpc_security_attributes :lp_security_attributes
52
+ ndr_uint32_ptr :lpdw_disposition
53
+
54
+ def initialize_instance
55
+ super
56
+ @opnum = REG_CREATE_KEY
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,36 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Winreg
4
+
5
+ class PrpcHkey < Ndr::NdrContextHandle; end
6
+
7
+ # This class represents a BaseRegCreateKey Response Packet as defined in
8
+ # [3.1.5.7 BaseRegCreateKey (Opnum 6)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/c7186ae2-1c82-45e9-933b-97d9873657e8)
9
+ class CreateKeyResponse < BinData::Record
10
+ # Create disposition
11
+ # The key did not exist and was created.
12
+ REG_CREATED_NEW_KEY = 0x00000001
13
+ # The key already existed and was opened without being changed.
14
+ REG_OPENED_EXISTING_KEY = 0x00000002
15
+
16
+ attr_reader :opnum
17
+
18
+ endian :little
19
+
20
+ prpc_hkey :hkey
21
+ ndr_uint32_ptr :lpdw_disposition
22
+ ndr_uint32 :error_status
23
+
24
+ def initialize_instance
25
+ super
26
+ @opnum = REG_CREATE_KEY
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+
36
+
@@ -12,33 +12,16 @@ module RubySMB
12
12
  endian :little
13
13
 
14
14
  rpc_hkey :hkey
15
- uint32 :dw_index
15
+ ndr_uint32 :dw_index
16
16
  rrp_unicode_string :lp_name
17
- string :pad1, length: -> { pad_length1 }
18
17
  prrp_unicode_string :lp_class
19
- string :pad2, length: -> { pad_length2 }
20
- ndr_lp_file_time :lpft_last_write_time
18
+ ndr_file_time_ptr :lpft_last_write_time
21
19
 
22
20
  def initialize_instance
23
21
  super
24
22
  @opnum = REG_ENUM_KEY
25
23
  end
26
-
27
- # Determines the correct length for the padding in front of
28
- # #lp_class. It should always force a 4-byte alignment.
29
- def pad_length1
30
- offset = (lp_name.abs_offset + lp_name.to_binary_s.length) % 4
31
- (4 - offset) % 4
32
- end
33
-
34
- # Determines the correct length for the padding in front of
35
- # #lpft_last_write_time. It should always force a 4-byte alignment.
36
- def pad_length2
37
- offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
38
- (4 - offset) % 4
39
- end
40
24
  end
41
-
42
25
  end
43
26
  end
44
27
  end
@@ -10,32 +10,15 @@ module RubySMB
10
10
  endian :little
11
11
 
12
12
  rrp_unicode_string :lp_name
13
- string :pad1, length: -> { pad_length1 }
14
- prrp_unicode_string :lp_class, initial_value: 0
15
- string :pad2, length: -> { pad_length2 }
16
- ndr_lp_file_time :lpft_last_write_time
17
- uint32 :error_status
13
+ prrp_unicode_string :lp_class
14
+ ndr_file_time_ptr :lpft_last_write_time
15
+ ndr_uint32 :error_status
18
16
 
19
17
  def initialize_instance
20
18
  super
21
19
  @opnum = REG_ENUM_KEY
22
20
  end
23
-
24
- # Determines the correct length for the padding in front of
25
- # #lp_class. It should always force a 4-byte alignment.
26
- def pad_length1
27
- offset = (lp_name.abs_offset + lp_name.to_binary_s.length) % 4
28
- (4 - offset) % 4
29
- end
30
-
31
- # Determines the correct length for the padding in front of
32
- # #lpft_last_write_time. It should always force a 4-byte alignment.
33
- def pad_length2
34
- offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
35
- (4 - offset) % 4
36
- end
37
21
  end
38
-
39
22
  end
40
23
  end
41
24
  end