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
@@ -12,27 +12,18 @@ 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_value_name
17
- string :pad, length: -> { pad_length }
18
- ndr_lp_dword :lp_type
19
- ndr_lp_byte :lp_data
20
- ndr_lp_dword :lpcb_data
21
- ndr_lp_dword :lpcb_len
17
+ ndr_uint32_ptr :lp_type
18
+ ndr_byte_array_ptr :lp_data
19
+ ndr_uint32_ptr :lpcb_data
20
+ ndr_uint32_ptr :lpcb_len
22
21
 
23
22
  def initialize_instance
24
23
  super
25
24
  @opnum = REG_ENUM_VALUE
26
25
  end
27
-
28
- # Determines the correct length for the padding in front of
29
- # #lp_type. It should always force a 4-byte alignment.
30
- def pad_length
31
- offset = (lp_value_name.abs_offset + lp_value_name.to_binary_s.length) % 4
32
- (4 - offset) % 4
33
- end
34
26
  end
35
-
36
27
  end
37
28
  end
38
29
  end
@@ -10,26 +10,17 @@ module RubySMB
10
10
  endian :little
11
11
 
12
12
  rrp_unicode_string :lp_value_name
13
- string :pad, length: -> { pad_length }
14
- ndr_lp_dword :lp_type
15
- ndr_lp_byte :lp_data
16
- ndr_lp_dword :lpcb_data
17
- ndr_lp_dword :lpcb_len
18
- uint32 :error_status
13
+ ndr_uint32_ptr :lp_type
14
+ ndr_byte_array_ptr :lp_data
15
+ ndr_uint32_ptr :lpcb_data
16
+ ndr_uint32_ptr :lpcb_len
17
+ ndr_uint32 :error_status
19
18
 
20
19
  def initialize_instance
21
20
  super
22
21
  @opnum = REG_ENUM_VALUE
23
22
  end
24
-
25
- # Determines the correct length for the padding in front of
26
- # #lp_type. It should always force a 4-byte alignment.
27
- def pad_length
28
- offset = (lp_value_name.abs_offset + lp_value_name.to_binary_s.length) % 4
29
- (4 - offset) % 4
30
- end
31
23
  end
32
-
33
24
  end
34
25
  end
35
26
  end
@@ -13,21 +13,13 @@ module RubySMB
13
13
 
14
14
  rpc_hkey :hkey
15
15
  rrp_unicode_string :lp_sub_key
16
- string :pad, length: -> { pad_length }
17
- uint32 :dw_options
16
+ ndr_uint32 :dw_options
18
17
  regsam :sam_desired
19
18
 
20
19
  def initialize_instance
21
20
  super
22
21
  @opnum = REG_OPEN_KEY
23
22
  end
24
-
25
- # Determines the correct length for the padding in front of
26
- # #dw_options. It should always force a 4-byte alignment.
27
- def pad_length
28
- offset = (lp_sub_key.abs_offset + lp_sub_key.to_binary_s.length) % 4
29
- (4 - offset) % 4
30
- end
31
23
  end
32
24
  end
33
25
  end
@@ -9,9 +9,10 @@ module RubySMB
9
9
  class OpenKeyResponse < BinData::Record
10
10
  attr_reader :opnum
11
11
 
12
- endian :little
13
- prpc_hkey :phk_result
14
- uint32 :error_status
12
+ endian :little
13
+
14
+ prpc_hkey :phk_result
15
+ ndr_uint32 :error_status
15
16
 
16
17
  def initialize_instance
17
18
  super
@@ -4,10 +4,9 @@ module RubySMB
4
4
 
5
5
  # This class represents a PREGISTRY_SERVER_NAME structure as defined in
6
6
  # [2.2.2 PREGISTRY_SERVER_NAME](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/8bcd15fd-1aa5-44e2-8662-112ec3e9817b)
7
- class PRegistryServerName < Ndr::NdrTopLevelFullPointer
8
- endian :little
9
-
10
- string16 :referent, read_length: -> { 4 }
7
+ class PRegistryServerName < BinData::Array
8
+ default_parameter type: :ndr_wide_char, referent_byte_align: 2
9
+ extend Ndr::PointerClassPlugin
11
10
  end
12
11
 
13
12
  # This class is a generic class that represents OpenXXX Request packet,
@@ -27,14 +26,14 @@ module RubySMB
27
26
  attr_reader :opnum
28
27
 
29
28
  endian :little
30
- p_registry_server_name :p_registry_server_name
29
+ p_registry_server_name :server_name
31
30
  regsam :sam_desired
32
31
 
33
32
  def initialize_instance
34
33
  super
35
34
  @opnum = get_parameter(:opnum) if has_parameter?(:opnum)
36
- p_registry_server_name.referent = "\0\0"
37
- sam_desired.maximum = 1 unless [OPEN_HKPD, OPEN_HKPT, OPEN_HKPN].include?(@opnum)
35
+ self.server_name = :null
36
+ self.sam_desired.maximum = 1 unless [OPEN_HKPD, OPEN_HKPT, OPEN_HKPN].include?(@opnum)
38
37
  end
39
38
  end
40
39
 
@@ -21,8 +21,8 @@ module RubySMB
21
21
  attr_reader :opnum
22
22
 
23
23
  endian :little
24
- prpc_hkey :ph_key
25
- uint32 :error_status
24
+ prpc_hkey :ph_key
25
+ ndr_uint32 :error_status
26
26
 
27
27
  def initialize_instance
28
28
  super
@@ -12,7 +12,7 @@ module RubySMB
12
12
  endian :little
13
13
 
14
14
  rpc_hkey :hkey
15
- rrp_unicode_string :lp_class, initial_value: 0
15
+ rrp_unicode_string :lp_class
16
16
 
17
17
  def initialize_instance
18
18
  super
@@ -9,30 +9,21 @@ module RubySMB
9
9
  endian :little
10
10
 
11
11
  rrp_unicode_string :lp_class, initial_value: 0
12
- string :pad, length: -> { pad_length }
13
- uint32 :lpc_sub_keys
14
- uint32 :lpc_max_sub_key_len
15
- uint32 :lpc_max_class_len
16
- uint32 :lpc_values
17
- uint32 :lpcb_max_value_name_len
18
- uint32 :lpcb_max_value_len
19
- uint32 :lpcb_security_descriptor
20
- file_time :lpft_last_write_time
21
- uint32 :error_status
12
+ ndr_uint32 :lpc_sub_keys
13
+ ndr_uint32 :lpc_max_sub_key_len
14
+ ndr_uint32 :lpc_max_class_len
15
+ ndr_uint32 :lpc_values
16
+ ndr_uint32 :lpcb_max_value_name_len
17
+ ndr_uint32 :lpcb_max_value_len
18
+ ndr_uint32 :lpcb_security_descriptor
19
+ ndr_file_time :lpft_last_write_time
20
+ ndr_uint32 :error_status
22
21
 
23
22
  def initialize_instance
24
23
  super
25
24
  @opnum = REG_QUERY_INFO_KEY
26
25
  end
27
-
28
- # Determines the correct length for the padding in front of
29
- # #lpc_sub_keys. It should always force a 4-byte alignment.
30
- def pad_length
31
- offset = (lp_class.abs_offset + lp_class.to_binary_s.length) % 4
32
- (4 - offset) % 4
33
- end
34
26
  end
35
-
36
27
  end
37
28
  end
38
29
  end
@@ -13,25 +13,16 @@ module RubySMB
13
13
 
14
14
  rpc_hkey :hkey
15
15
  rrp_unicode_string :lp_value_name
16
- string :pad, length: -> { pad_length }
17
- ndr_lp_dword :lp_type
18
- ndr_lp_byte :lp_data
19
- ndr_lp_dword :lpcb_data
20
- ndr_lp_dword :lpcb_len
16
+ ndr_uint32_ptr :lp_type
17
+ ndr_byte_array_ptr :lp_data
18
+ ndr_uint32_ptr :lpcb_data
19
+ ndr_uint32_ptr :lpcb_len
21
20
 
22
21
  def initialize_instance
23
22
  super
24
23
  @opnum = REG_QUERY_VALUE
25
24
  end
26
-
27
- # Determines the correct length for the padding in front of
28
- # #lp_type. It should always force a 4-byte alignment.
29
- def pad_length
30
- offset = (lp_value_name.abs_offset + lp_value_name.to_binary_s.length) % 4
31
- (4 - offset) % 4
32
- end
33
25
  end
34
-
35
26
  end
36
27
  end
37
28
  end
@@ -9,29 +9,21 @@ module RubySMB
9
9
 
10
10
  endian :little
11
11
 
12
- ndr_lp_dword :lp_type
13
- ndr_lp_byte :lp_data
14
- string :pad, length: -> { pad_length }
15
- ndr_lp_dword :lpcb_data
16
- ndr_lp_dword :lpcb_len
17
- uint32 :error_status
12
+ ndr_uint32_ptr :lp_type
13
+ ndr_byte_array_ptr :lp_data
14
+ ndr_uint32_ptr :lpcb_data
15
+ ndr_uint32_ptr :lpcb_len
16
+ ndr_uint32 :error_status
18
17
 
19
18
  def initialize_instance
20
19
  super
21
20
  @opnum = REG_QUERY_VALUE
22
21
  end
23
22
 
24
- # Determines the correct length for the padding in front of
25
- # #lpcb_data. It should always force a 4-byte alignment.
26
- def pad_length
27
- offset = (lp_data.abs_offset + lp_data.to_binary_s.length) % 4
28
- (4 - offset) % 4
29
- end
30
-
31
23
  # Returns the data portion of the registry value formatted according to its type:
32
24
  # [3.1.1.5 Values](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/3d64dbea-f016-4373-8cac-e43bf343837d)
33
25
  def data
34
- bytes = lp_data.bytes.to_a.pack('C*')
26
+ bytes = lp_data.to_a.pack('C*')
35
27
  case lp_type
36
28
  when 1,2
37
29
  bytes.force_encoding('utf-16le').strip
@@ -47,7 +39,7 @@ module RubySMB
47
39
  when 11
48
40
  bytes.unpack('Q<').first
49
41
  else
50
- ""
42
+ ''
51
43
  end
52
44
  end
53
45
 
@@ -5,8 +5,10 @@ module RubySMB
5
5
  # This class represents a REGSAM structure as defined in
6
6
  # [2.2.3 REGSAM](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/fefbc801-b141-4bb1-9dcb-bf366da3ae7e)
7
7
  # [2.4.3 ACCESS_MASK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b)
8
- class Regsam < BinData::Record
8
+ class Regsam < Ndr::NdrStruct
9
+ default_parameter byte_align: 4
9
10
  endian :little
11
+
10
12
  bit2 :reserved, label: 'Reserved Space'
11
13
  bit1 :key_create_link, label: 'Key Create Link'
12
14
  bit1 :key_notify, label: 'Key Notify'
@@ -0,0 +1,28 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Winreg
4
+
5
+ class RpcHkey < Ndr::NdrContextHandle; end
6
+
7
+ # This class represents a BaseRegSaveKey Request Packet as defined in
8
+ # [3.1.5.20 BaseRegSaveKey (Opnum 20)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/f022247d-6ef1-4f46-b195-7f60654f4a0d)
9
+ class SaveKeyRequest < BinData::Record
10
+ attr_reader :opnum
11
+
12
+ endian :little
13
+
14
+ rpc_hkey :hkey
15
+ rrp_unicode_string :lp_file
16
+ prpc_security_attributes :lp_security_attributes
17
+
18
+ def initialize_instance
19
+ super
20
+ @opnum = REG_SAVE_KEY
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+
@@ -0,0 +1,23 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Winreg
4
+
5
+ # This class represents a BaseRegSaveKey Response Packet as defined in
6
+ # [3.1.5.20 BaseRegSaveKey (Opnum 20)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rrp/f022247d-6ef1-4f46-b195-7f60654f4a0d)
7
+ class SaveKeyResponse < BinData::Record
8
+ attr_reader :opnum
9
+
10
+ endian :little
11
+
12
+ ndr_uint32 :error_status
13
+
14
+ def initialize_instance
15
+ super
16
+ @opnum = REG_CREATE_KEY
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -13,11 +13,13 @@ module RubySMB
13
13
  OPEN_HKPD = 0x03
14
14
  OPEN_HKU = 0x04
15
15
  REG_CLOSE_KEY = 0x05
16
+ REG_CREATE_KEY = 0x06
16
17
  REG_ENUM_KEY = 0x09
17
18
  REG_ENUM_VALUE = 0x0a
18
19
  REG_OPEN_KEY = 0x0f
19
20
  REG_QUERY_INFO_KEY = 0x10
20
21
  REG_QUERY_VALUE = 0x11
22
+ REG_SAVE_KEY = 0x14
21
23
  OPEN_HKCC = 0x1b
22
24
  OPEN_HKPT = 0x20
23
25
  OPEN_HKPN = 0x21
@@ -37,6 +39,10 @@ module RubySMB
37
39
  require 'ruby_smb/dcerpc/winreg/query_info_key_response'
38
40
  require 'ruby_smb/dcerpc/winreg/query_value_request'
39
41
  require 'ruby_smb/dcerpc/winreg/query_value_response'
42
+ require 'ruby_smb/dcerpc/winreg/create_key_request'
43
+ require 'ruby_smb/dcerpc/winreg/create_key_response'
44
+ require 'ruby_smb/dcerpc/winreg/save_key_request'
45
+ require 'ruby_smb/dcerpc/winreg/save_key_response'
40
46
 
41
47
  ROOT_KEY_MAP = {
42
48
  "HKEY_CLASSES_ROOT" => OPEN_HKCR,
@@ -57,6 +63,8 @@ module RubySMB
57
63
  "HKPN" => OPEN_HKPN
58
64
  }
59
65
 
66
+ BUFFER_SIZE = 1024
67
+
60
68
  # Open the registry root key and return a handle for it. The key can be
61
69
  # either a long format (e.g. HKEY_LOCAL_MACHINE) or a short format
62
70
  # (e.g. HKLM)
@@ -125,7 +133,9 @@ module RubySMB
125
133
  # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
126
134
  def query_value(handle, value_name)
127
135
  query_value_request_packet = RubySMB::Dcerpc::Winreg::QueryValueRequest.new(hkey: handle, lp_value_name: value_name)
128
- query_value_request_packet.lp_data.referent_identifier = 0
136
+ query_value_request_packet.lp_type = 0
137
+ query_value_request_packet.lpcb_data = 0
138
+ query_value_request_packet.lpcb_len = 0
129
139
  response = dcerpc_request(query_value_request_packet)
130
140
  begin
131
141
  query_value_response = RubySMB::Dcerpc::Winreg::QueryValueResponse.read(response)
@@ -137,9 +147,9 @@ module RubySMB
137
147
  "#{WindowsError::Win32.find_by_retval(query_value_response.error_status.value).join(',')}"
138
148
  end
139
149
 
140
- query_value_request_packet = RubySMB::Dcerpc::Winreg::QueryValueRequest.new(hkey: handle, lp_value_name: value_name)
141
150
  query_value_request_packet.lpcb_data = query_value_response.lpcb_data
142
- query_value_request_packet.lp_data.max_count = query_value_response.lpcb_data.referent
151
+ query_value_request_packet.lp_data = []
152
+ query_value_request_packet.lp_data.max_count = query_value_response.lpcb_data.to_i
143
153
  response = dcerpc_request(query_value_request_packet)
144
154
  begin
145
155
  query_value_response = RubySMB::Dcerpc::Winreg::QueryValueResponse.read(response)
@@ -185,6 +195,7 @@ module RubySMB
185
195
  # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
186
196
  def query_info_key(handle)
187
197
  query_info_key_request_packet = RubySMB::Dcerpc::Winreg::QueryInfoKeyRequest.new(hkey: handle)
198
+ query_info_key_request_packet.lp_class.set_max_buffer_size(BUFFER_SIZE)
188
199
  response = dcerpc_request(query_info_key_request_packet)
189
200
  begin
190
201
  query_info_key_response = RubySMB::Dcerpc::Winreg::QueryInfoKeyResponse.read(response)
@@ -208,9 +219,9 @@ module RubySMB
208
219
  # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
209
220
  def enum_key(handle, index)
210
221
  enum_key_request_packet = RubySMB::Dcerpc::Winreg::EnumKeyRequest.new(hkey: handle, dw_index: index)
211
- enum_key_request_packet.lpft_last_write_time = 0
212
- enum_key_request_packet.lp_class.referent.buffer = 0
213
- enum_key_request_packet.lp_name.buffer.referent.max_count = 256
222
+ # `lp_class` cannot be null, even if it contains no value
223
+ enum_key_request_packet.lp_class.instantiate_referent
224
+ enum_key_request_packet.lp_name.set_max_buffer_size(BUFFER_SIZE)
214
225
  response = dcerpc_request(enum_key_request_packet)
215
226
  begin
216
227
  enum_key_response = RubySMB::Dcerpc::Winreg::EnumKeyResponse.read(response)
@@ -222,7 +233,7 @@ module RubySMB
222
233
  "#{WindowsError::Win32.find_by_retval(enum_key_response.error_status.value).join(',')}"
223
234
  end
224
235
 
225
- enum_key_response.lp_name.to_s
236
+ enum_key_response.lp_name[:buffer]
226
237
  end
227
238
 
228
239
  # Enumerate the value at the specified index for the specified registry key.
@@ -234,8 +245,7 @@ module RubySMB
234
245
  # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
235
246
  def enum_value(handle, index)
236
247
  enum_value_request_packet = RubySMB::Dcerpc::Winreg::EnumValueRequest.new(hkey: handle, dw_index: index)
237
- enum_value_request_packet.lp_data.referent_identifier = 0
238
- enum_value_request_packet.lp_value_name.buffer.referent.max_count = 256
248
+ enum_value_request_packet.lp_value_name.set_max_buffer_size(BUFFER_SIZE)
239
249
  response = dcerpc_request(enum_value_request_packet)
240
250
  begin
241
251
  enum_value_response = RubySMB::Dcerpc::Winreg::EnumValueResponse.read(response)
@@ -247,7 +257,66 @@ module RubySMB
247
257
  "#{WindowsError::Win32.find_by_retval(enum_value_response.error_status.value).join(',')}"
248
258
  end
249
259
 
250
- enum_value_response.lp_value_name.to_s
260
+ enum_value_response.lp_value_name[:buffer]
261
+ end
262
+
263
+ # Creates the specified registry key and returns a handle to the newly created key
264
+ #
265
+ # @param handle [Ndr::NdrContextHandle] the handle for the key
266
+ # @param sub_key [String] the name of the key
267
+ # @param opts [Hash] options for the CreateKeyRequest
268
+ # @return [RubySMB::Dcerpc::Winreg::PrpcHkey] the handle to the opened or created key
269
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a CreateKeyResponse packet
270
+ # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
271
+ def create_key(handle, sub_key, opts = {})
272
+ opts = {
273
+ hkey: handle,
274
+ lp_sub_key: sub_key,
275
+ lp_class: opts[:lp_class] || :null,
276
+ dw_options: opts[:dw_options] || RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_VOLATILE,
277
+ sam_desired: opts[:sam_desired] || RubySMB::Dcerpc::Winreg::Regsam.new(maximum: 1),
278
+ lp_security_attributes: opts[:lp_security_attributes] || RubySMB::Dcerpc::RpcSecurityAttributes.new,
279
+ lpdw_disposition: opts[:lpdw_disposition] || RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_CREATED_NEW_KEY,
280
+ }
281
+ create_key_request_packet = RubySMB::Dcerpc::Winreg::CreateKeyRequest.new(opts)
282
+ response = dcerpc_request(create_key_request_packet)
283
+ begin
284
+ create_key_response = RubySMB::Dcerpc::Winreg::CreateKeyResponse.read(response)
285
+ rescue IOError
286
+ raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the CreateKey response"
287
+ end
288
+ unless create_key_response.error_status == WindowsError::Win32::ERROR_SUCCESS
289
+ raise RubySMB::Dcerpc::Error::WinregError, "Error returned when creating key #{sub_key}: "\
290
+ "#{WindowsError::Win32.find_by_retval(create_key_response.error_status.value).join(',')}"
291
+ end
292
+
293
+ create_key_response.hkey
294
+ end
295
+
296
+ # Saves the specified key, subkeys, and values to a new file
297
+ #
298
+ # @param handle [Ndr::NdrContextHandle] the handle for the key
299
+ # @param file_name [String] the name of the registry file in which the specified key and subkeys are to be saved
300
+ # @param opts [Hash] options for the SaveKeyRequest
301
+ # @raise [RubySMB::Dcerpc::Error::InvalidPacket] if the response is not a SaveKeyResponse packet
302
+ # @raise [RubySMB::Dcerpc::Error::WinregError] if the response error status is not ERROR_SUCCESS
303
+ def save_key(handle, file_name, opts = {})
304
+ opts = {
305
+ hkey: handle,
306
+ lp_file: file_name,
307
+ lp_security_attributes: opts[:lp_security_attributes] || :null,
308
+ }
309
+ save_key_request_packet = RubySMB::Dcerpc::Winreg::SaveKeyRequest.new(opts)
310
+ response = dcerpc_request(save_key_request_packet)
311
+ begin
312
+ save_key_response = RubySMB::Dcerpc::Winreg::SaveKeyResponse.read(response)
313
+ rescue IOError
314
+ raise RubySMB::Dcerpc::Error::InvalidPacket, "Error reading the SaveKeyResponse response"
315
+ end
316
+ unless save_key_response.error_status == WindowsError::Win32::ERROR_SUCCESS
317
+ raise RubySMB::Dcerpc::Error::WinregError, "Error returned when saving key to #{file_name}: "\
318
+ "#{WindowsError::Win32.find_by_retval(save_key_response.error_status.value).join(',')}"
319
+ end
251
320
  end
252
321
 
253
322
  # Checks if the specified registry key exists. It returns true if it
@@ -255,8 +324,8 @@ module RubySMB
255
324
  #
256
325
  # @param key [String] the registry key to check
257
326
  # @return [Boolean]
258
- def has_registry_key?(key)
259
- bind(endpoint: RubySMB::Dcerpc::Winreg)
327
+ def has_registry_key?(key, bind: true)
328
+ bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
260
329
 
261
330
  root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
262
331
  begin
@@ -265,8 +334,10 @@ module RubySMB
265
334
  rescue RubySMB::Dcerpc::Error::WinregError
266
335
  return false
267
336
  end
268
- close_key(subkey_handle)
269
337
  return true
338
+ ensure
339
+ close_key(subkey_handle) if subkey_handle
340
+ close_key(root_key_handle) if root_key_handle
270
341
  end
271
342
 
272
343
  # Retrieve the data associated with the named value of a specified
@@ -275,15 +346,17 @@ module RubySMB
275
346
  # @param key [String] the registry key
276
347
  # @param value_name [String] the name of the value to read
277
348
  # @return [String] the data of the value entry
278
- def read_registry_key_value(key, value_name)
279
- bind(endpoint: RubySMB::Dcerpc::Winreg)
349
+ def read_registry_key_value(key, value_name, bind: true)
350
+ bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
280
351
 
281
352
  root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
282
353
  root_key_handle = open_root_key(root_key)
283
354
  subkey_handle = open_key(root_key_handle, sub_key)
284
355
  value = query_value(subkey_handle, value_name)
285
- close_key(subkey_handle)
286
356
  value
357
+ ensure
358
+ close_key(subkey_handle) if subkey_handle
359
+ close_key(root_key_handle) if root_key_handle
287
360
  end
288
361
 
289
362
  # Enumerate the subkeys of a specified registry key. If only a root key
@@ -291,8 +364,8 @@ module RubySMB
291
364
  #
292
365
  # @param key [String] the registry key
293
366
  # @return [Array<String>] the subkeys
294
- def enum_registry_key(key)
295
- bind(endpoint: RubySMB::Dcerpc::Winreg)
367
+ def enum_registry_key(key, bind: true)
368
+ bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
296
369
 
297
370
  root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
298
371
  root_key_handle = open_root_key(root_key)
@@ -307,16 +380,18 @@ module RubySMB
307
380
  key_count.times do |i|
308
381
  enum_result << enum_key(subkey_handle, i)
309
382
  end
310
- close_key(subkey_handle)
311
383
  enum_result
384
+ ensure
385
+ close_key(subkey_handle) if subkey_handle
386
+ close_key(root_key_handle) if root_key_handle && root_key_handle != subkey_handle
312
387
  end
313
388
 
314
389
  # Enumerate the values for the specified registry key.
315
390
  #
316
391
  # @param key [String] the registry key
317
392
  # @return [Array<String>] the values
318
- def enum_registry_values(key)
319
- bind(endpoint: RubySMB::Dcerpc::Winreg)
393
+ def enum_registry_values(key, bind: true)
394
+ bind(endpoint: RubySMB::Dcerpc::Winreg) if bind
320
395
 
321
396
  root_key, sub_key = key.gsub(/\//, '\\').split('\\', 2)
322
397
  root_key_handle = open_root_key(root_key)
@@ -331,8 +406,10 @@ module RubySMB
331
406
  value_count.times do |i|
332
407
  enum_result << enum_value(subkey_handle, i)
333
408
  end
334
- close_key(subkey_handle)
335
409
  enum_result
410
+ ensure
411
+ close_key(subkey_handle) if subkey_handle
412
+ close_key(root_key_handle) if root_key_handle && root_key_handle != subkey_handle
336
413
  end
337
414
 
338
415
  end
@@ -0,0 +1,26 @@
1
+ module RubySMB
2
+ module Dcerpc
3
+ module Wkssvc
4
+
5
+ # [2.2.2.1 WKSSVC_IDENTIFY_HANDLE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/9ef94a11-0e5c-49d7-9ac7-68d6f03565de)
6
+ class WkssvcIdentifyHandle < Ndr::NdrWideStringPtr; end
7
+
8
+ # [3.2.4.1 NetrWkstaGetInfo (Opnum 0)](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wkst/4af41d6f-b800-4de1-af5b-0b15a85f8e04)
9
+ class NetrWkstaGetInfoRequest < BinData::Record
10
+ attr_reader :opnum
11
+
12
+ endian :little
13
+
14
+ wkssvc_identify_handle :server_name
15
+ ndr_uint32 :level
16
+
17
+ def initialize_instance
18
+ super
19
+ @opnum = NETR_WKSTA_GET_INFO
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+