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
@@ -132,36 +132,34 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
132
132
  describe '#query_value' do
133
133
  let(:handle) { double('Handle') }
134
134
  let(:value_name) { double('Value Name') }
135
- let(:query_value_request_packet1) { double('Query Value Request Packet #1') }
136
- let(:query_value_request_packet2) { double('Query Value Request Packet #2') }
137
- let(:lp_data1) { double('LpData #1') }
138
- let(:lp_data2) { double('LpData #2') }
135
+ let(:query_value_request_packet) { double('Query Value Request Packet #1') }
136
+ let(:lp_data) { double('LpData #2') }
139
137
  let(:response1) { double('Response #1') }
140
138
  let(:response2) { double('Response #2') }
141
139
  let(:query_value_response1) { double('Query Value Response #1') }
142
140
  let(:query_value_response2) { double('Query Value Response #2') }
143
141
  let(:data) { double('Data') }
144
142
  let(:lpcb_data) { double('LpcbData') }
145
- let(:lpcb_data_referent) { double('Lpcb Data Referent') }
143
+ let(:max_count) { 5 }
146
144
  before :example do
145
+ allow(described_class::QueryValueRequest).to receive(:new).and_return(query_value_request_packet)
146
+ allow(query_value_request_packet).to receive_messages(
147
+ :lp_type= => nil,
148
+ :lpcb_data= => nil,
149
+ :lpcb_len= => nil,
150
+ :lp_data= => nil,
151
+ :lp_data => lp_data,
152
+ )
153
+ allow(lp_data).to receive(:max_count=)
147
154
  first_request = true
148
- allow(described_class::QueryValueRequest).to receive(:new) do
155
+ allow(winreg).to receive(:dcerpc_request) do |arg|
149
156
  if first_request
150
157
  first_request = false
151
- query_value_request_packet1
158
+ response1
152
159
  else
153
- query_value_request_packet2
160
+ response2
154
161
  end
155
162
  end
156
- allow(query_value_request_packet1).to receive(:lp_data).and_return(lp_data1)
157
- allow(query_value_request_packet2).to receive_messages(
158
- :lp_data => lp_data2,
159
- :lpcb_data= => nil
160
- )
161
- allow(lp_data1).to receive(:referent_identifier=)
162
- allow(lp_data2).to receive(:max_count=)
163
- allow(winreg).to receive(:dcerpc_request).with(query_value_request_packet1).and_return(response1)
164
- allow(winreg).to receive(:dcerpc_request).with(query_value_request_packet2).and_return(response2)
165
163
  allow(described_class::QueryValueResponse).to receive(:read).with(response1).and_return(query_value_response1)
166
164
  allow(described_class::QueryValueResponse).to receive(:read).with(response2).and_return(query_value_response2)
167
165
  allow(query_value_response1).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
@@ -170,29 +168,27 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
170
168
  :data => data
171
169
  )
172
170
  allow(query_value_response1).to receive(:lpcb_data).and_return(lpcb_data)
173
- allow(lpcb_data).to receive(:referent).and_return(lpcb_data_referent)
171
+ allow(lpcb_data).to receive(:to_i).and_return(max_count)
174
172
  end
175
173
 
176
174
  it 'create the expected QueryValueRequest packets' do
177
175
  winreg.query_value(handle, value_name)
178
- expect(described_class::QueryValueRequest).to have_received(:new).with(hkey: handle, lp_value_name: value_name).twice
179
- end
180
-
181
- it 'sets the expected user rights on the first request packet' do
182
- winreg.query_value(handle, value_name)
183
- expect(lp_data1).to have_received(:referent_identifier=).with(0)
176
+ expect(described_class::QueryValueRequest).to have_received(:new).with(hkey: handle, lp_value_name: value_name)
184
177
  end
185
178
 
186
- it 'sets the expected user rights on the second request packet' do
179
+ it 'sets the expected fields on the request packet' do
187
180
  winreg.query_value(handle, value_name)
188
- expect(lp_data2).to have_received(:max_count=).with(lpcb_data_referent)
189
- expect(query_value_request_packet2).to have_received(:lpcb_data=).with(lpcb_data)
181
+ expect(query_value_request_packet).to have_received(:lp_type=).with(0)
182
+ expect(query_value_request_packet).to have_received(:lpcb_data=).with(0)
183
+ expect(query_value_request_packet).to have_received(:lpcb_len=).with(0)
184
+ expect(query_value_request_packet).to have_received(:lpcb_data=).with(lpcb_data)
185
+ expect(query_value_request_packet).to have_received(:lp_data=).with([])
186
+ expect(lp_data).to have_received(:max_count=).with(max_count)
190
187
  end
191
188
 
192
189
  it 'sends the expected dcerpc requests' do
193
190
  winreg.query_value(handle, value_name)
194
- expect(winreg).to have_received(:dcerpc_request).with(query_value_request_packet1).once.ordered
195
- expect(winreg).to have_received(:dcerpc_request).with(query_value_request_packet2).once.ordered
191
+ expect(winreg).to have_received(:dcerpc_request).with(query_value_request_packet).twice
196
192
  end
197
193
 
198
194
  context 'when receiving the first response' do
@@ -293,8 +289,14 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
293
289
  let(:query_info_key_request_packet) { double('CloseKey Request Packet') }
294
290
  let(:response) { double('Response') }
295
291
  let(:query_info_key_response) { double('CloseKey Response') }
292
+ let(:lp_class) { double('LpClass') }
296
293
  before :example do
297
294
  allow(described_class::QueryInfoKeyRequest).to receive(:new).and_return(query_info_key_request_packet)
295
+ allow(query_info_key_request_packet).to receive_messages(
296
+ :lp_class= => nil,
297
+ :lp_class => lp_class,
298
+ )
299
+ allow(lp_class).to receive(:set_max_buffer_size)
298
300
  allow(winreg).to receive(:dcerpc_request).and_return(response)
299
301
  allow(described_class::QueryInfoKeyResponse).to receive(:read).and_return(query_info_key_response)
300
302
  allow(query_info_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
@@ -310,6 +312,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
310
312
  expect(winreg).to have_received(:dcerpc_request).with(query_info_key_request_packet)
311
313
  end
312
314
 
315
+ it 'sets the expected fields on the request packet' do
316
+ winreg.query_info_key(handle)
317
+ expect(lp_class).to have_received(:set_max_buffer_size).with(RubySMB::Dcerpc::Winreg::BUFFER_SIZE)
318
+ end
319
+
313
320
  it 'creates a QueryInfoKeyResponse structure from the expected dcerpc response' do
314
321
  winreg.query_info_key(handle)
315
322
  expect(described_class::QueryInfoKeyResponse).to have_received(:read).with(response)
@@ -338,30 +345,23 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
338
345
  let(:handle) { double('Handle') }
339
346
  let(:index) { double('Index') }
340
347
  let(:enum_key_request_packet) { double('enum_key Request Packet') }
341
- let(:lp_class) { double('Lp Class') }
342
348
  let(:lp_name) { double('Lp Name') }
343
- let(:buffer) { double('Buffer') }
344
- let(:lp_class_buffer_referent) { double('Lp Class buffer referent') }
345
- let(:lp_name_buffer_referent) { double('Lp Name buffer referent') }
346
349
  let(:response) { double('Response') }
347
350
  let(:enum_key_response) { double('enum_key Response') }
348
- let(:result_str) { double('Result String') }
351
+ let(:result_str) { { buffer: 'reg key' } }
352
+ let(:lp_class) { double('Lp Class') }
349
353
  before :example do
350
354
  allow(described_class::EnumKeyRequest).to receive(:new).and_return(enum_key_request_packet)
351
355
  allow(enum_key_request_packet).to receive_messages(
352
- :lpft_last_write_time= => nil,
353
- :lp_class => lp_class,
354
- :lp_name => lp_name
356
+ :lp_name => lp_name,
357
+ :lp_class => lp_class
355
358
  )
356
- allow(lp_class).to receive(:referent).and_return(lp_class_buffer_referent)
357
- allow(lp_name).to receive(:buffer).and_return(buffer)
358
- allow(buffer).to receive(:referent).and_return(lp_name_buffer_referent)
359
- allow(lp_class_buffer_referent).to receive(:buffer=)
360
- allow(lp_name_buffer_referent).to receive(:max_count=)
359
+ allow(lp_class).to receive(:instantiate_referent)
360
+ allow(lp_name).to receive(:set_max_buffer_size)
361
361
  allow(winreg).to receive(:dcerpc_request).and_return(response)
362
362
  allow(described_class::EnumKeyResponse).to receive(:read).and_return(enum_key_response)
363
363
  allow(enum_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
364
- allow(enum_key_response).to receive_message_chain(:lp_name, :to_s => result_str)
364
+ allow(enum_key_response).to receive_message_chain(:lp_name, :[] => result_str)
365
365
  end
366
366
 
367
367
  it 'create the expected EnumKeyRequest packet' do
@@ -369,11 +369,10 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
369
369
  expect(described_class::EnumKeyRequest).to have_received(:new).with(hkey: handle, dw_index: index)
370
370
  end
371
371
 
372
- it 'sets the expected user rights on the request packet' do
372
+ it 'sets the expected parameters on the request packet' do
373
373
  winreg.enum_key(handle, index)
374
- expect(enum_key_request_packet).to have_received(:lpft_last_write_time=).with(0)
375
- expect(lp_class_buffer_referent).to have_received(:buffer=).with(0)
376
- expect(lp_name_buffer_referent).to have_received(:max_count=).with(256)
374
+ expect(lp_class).to have_received(:instantiate_referent)
375
+ expect(lp_name).to have_received(:set_max_buffer_size).with(RubySMB::Dcerpc::Winreg::BUFFER_SIZE)
377
376
  end
378
377
 
379
378
  it 'sends the expected dcerpc request' do
@@ -410,26 +409,18 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
410
409
  let(:index) { double('Index') }
411
410
  let(:enum_value_request_packet) { double('EnumValue Request Packet') }
412
411
  let(:lp_value_name) { double('Lp Value Name') }
413
- let(:lp_data) { double('Lp Data') }
414
- let(:buffer) { double('Buffer') }
415
412
  let(:referent) { double('Referent') }
416
413
  let(:response) { double('Response') }
417
414
  let(:enum_value_response) { double('EnumValue Response') }
418
- let(:result_str) { double('Result String') }
415
+ let(:result_str) { {buffer: 'reg value'} }
419
416
  before :example do
420
417
  allow(described_class::EnumValueRequest).to receive(:new).and_return(enum_value_request_packet)
421
- allow(enum_value_request_packet).to receive_messages(
422
- :lp_value_name => lp_value_name,
423
- :lp_data => lp_data
424
- )
425
- allow(lp_value_name).to receive(:buffer).and_return(buffer)
426
- allow(buffer).to receive(:referent).and_return(referent)
427
- allow(referent).to receive(:max_count=)
428
- allow(lp_data).to receive(:referent_identifier=)
418
+ allow(enum_value_request_packet).to receive(:lp_value_name).and_return(lp_value_name)
419
+ allow(lp_value_name).to receive(:set_max_buffer_size)
429
420
  allow(winreg).to receive(:dcerpc_request).and_return(response)
430
421
  allow(described_class::EnumValueResponse).to receive(:read).and_return(enum_value_response)
431
422
  allow(enum_value_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
432
- allow(enum_value_response).to receive_message_chain(:lp_value_name, :to_s => result_str)
423
+ allow(enum_value_response).to receive_message_chain(:lp_value_name, :[] => result_str)
433
424
  end
434
425
 
435
426
  it 'create the expected EnumValueRequest packet' do
@@ -437,10 +428,9 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
437
428
  expect(described_class::EnumValueRequest).to have_received(:new).with(hkey: handle, dw_index: index)
438
429
  end
439
430
 
440
- it 'sets the expected user rights on the request packet' do
431
+ it 'sets the expected buffer on the request packet' do
441
432
  winreg.enum_value(handle, index)
442
- expect(referent).to have_received(:max_count=).with(256)
443
- expect(lp_data).to have_received(:referent_identifier=).with(0)
433
+ expect(lp_value_name).to have_received(:set_max_buffer_size).with(RubySMB::Dcerpc::Winreg::BUFFER_SIZE)
444
434
  end
445
435
 
446
436
  it 'sends the expected dcerpc request' do
@@ -492,6 +482,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
492
482
  expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
493
483
  end
494
484
 
485
+ it 'does not bind a DCERPC connection if #bind argument is false' do
486
+ winreg.has_registry_key?(key, bind: false)
487
+ expect(winreg).to_not have_received(:bind)
488
+ end
489
+
495
490
  it 'opens the expected root key' do
496
491
  winreg.has_registry_key?(key)
497
492
  expect(winreg).to have_received(:open_root_key).with(root_key)
@@ -519,6 +514,7 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
519
514
  it 'closes the key' do
520
515
  winreg.has_registry_key?(key)
521
516
  expect(winreg).to have_received(:close_key).with(subkey_handle)
517
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
522
518
  end
523
519
 
524
520
  it 'returns true when no error occurs' do
@@ -549,6 +545,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
549
545
  expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
550
546
  end
551
547
 
548
+ it 'does not bind a DCERPC connection if #bind argument is false' do
549
+ winreg.read_registry_key_value(key, value_name, bind: false)
550
+ expect(winreg).to_not have_received(:bind)
551
+ end
552
+
552
553
  it 'opens the expected root key' do
553
554
  winreg.read_registry_key_value(key, value_name)
554
555
  expect(winreg).to have_received(:open_root_key).with(root_key)
@@ -567,6 +568,7 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
567
568
  it 'closes the key' do
568
569
  winreg.read_registry_key_value(key, value_name)
569
570
  expect(winreg).to have_received(:close_key).with(subkey_handle)
571
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
570
572
  end
571
573
 
572
574
  it 'returns expect registry key value' do
@@ -600,6 +602,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
600
602
  expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
601
603
  end
602
604
 
605
+ it 'does not bind a DCERPC connection if #bind argument is false' do
606
+ winreg.enum_registry_key(key, bind: false)
607
+ expect(winreg).to_not have_received(:bind)
608
+ end
609
+
603
610
  it 'opens the expected root key' do
604
611
  winreg.enum_registry_key(key)
605
612
  expect(winreg).to have_received(:open_root_key).with(root_key)
@@ -630,6 +637,13 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
630
637
  it 'closes the key' do
631
638
  winreg.enum_registry_key(key)
632
639
  expect(winreg).to have_received(:close_key).with(subkey_handle)
640
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
641
+ end
642
+
643
+ it 'only closes the key once when there is no subkey' do
644
+ winreg.enum_registry_key(root_key)
645
+ expect(winreg).to have_received(:close_key).once
646
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
633
647
  end
634
648
 
635
649
  it 'returns the expected array of enumerated keys' do
@@ -667,6 +681,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
667
681
  expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
668
682
  end
669
683
 
684
+ it 'does not bind a DCERPC connection if #bind argument is false' do
685
+ winreg.enum_registry_values(key, bind: false)
686
+ expect(winreg).to_not have_received(:bind)
687
+ end
688
+
670
689
  it 'opens the expected root key' do
671
690
  winreg.enum_registry_values(key)
672
691
  expect(winreg).to have_received(:open_root_key).with(root_key)
@@ -697,6 +716,13 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
697
716
  it 'closes the key' do
698
717
  winreg.enum_registry_values(key)
699
718
  expect(winreg).to have_received(:close_key).with(subkey_handle)
719
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
720
+ end
721
+
722
+ it 'only closes the key once when there is no subkey' do
723
+ winreg.enum_registry_values(root_key)
724
+ expect(winreg).to have_received(:close_key).once
725
+ expect(winreg).to have_received(:close_key).with(root_key_handle)
700
726
  end
701
727
 
702
728
  it 'returns the expected array of enumerated keys' do
@@ -707,4 +733,135 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
707
733
  expect(winreg.enum_registry_values(key)).to eq([value1, value2])
708
734
  end
709
735
  end
736
+
737
+ describe '#create_key' do
738
+ let(:handle) { double('Handle') }
739
+ let(:sub_key) { double('Sub key') }
740
+ let(:create_key_request) { double('CreateKey Request') }
741
+ let(:response) { double('Response') }
742
+ let(:create_key_response) { double('CreateKey Response') }
743
+ let(:hkey) { double('hkey') }
744
+ before :example do
745
+ allow(described_class::CreateKeyRequest).to receive(:new).and_return(create_key_request)
746
+ allow(winreg).to receive(:dcerpc_request).and_return(response)
747
+ allow(described_class::CreateKeyResponse).to receive(:read).and_return(create_key_response)
748
+ allow(create_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
749
+ allow(create_key_response).to receive(:hkey).and_return(hkey)
750
+ end
751
+
752
+ it 'create the expected CreateKeyRequest packet with the default options' do
753
+ opts = {
754
+ hkey: handle,
755
+ lp_sub_key: sub_key,
756
+ lp_class: :null,
757
+ dw_options: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_VOLATILE,
758
+ sam_desired: RubySMB::Dcerpc::Winreg::Regsam.new(maximum: 1),
759
+ lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new,
760
+ lpdw_disposition: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_CREATED_NEW_KEY
761
+ }
762
+ winreg.create_key(handle, sub_key)
763
+ expect(described_class::CreateKeyRequest).to have_received(:new).with(opts)
764
+ end
765
+
766
+ it 'create the expected CreateKeyRequest packet with custom options' do
767
+ opts = {
768
+ hkey: handle,
769
+ lp_sub_key: sub_key,
770
+ lp_class: 'MyClass',
771
+ dw_options: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_SYMLINK,
772
+ sam_desired: RubySMB::Dcerpc::Winreg::Regsam.new(key_set_value: 1),
773
+ lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new(n_length: 3),
774
+ lpdw_disposition: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_OPENED_EXISTING_KEY
775
+ }
776
+ winreg.create_key(handle, sub_key, opts)
777
+ expect(described_class::CreateKeyRequest).to have_received(:new).with(opts)
778
+ end
779
+
780
+ it 'sends the expected dcerpc request' do
781
+ winreg.create_key(handle, sub_key)
782
+ expect(winreg).to have_received(:dcerpc_request).with(create_key_request)
783
+ end
784
+
785
+ it 'creates a CreateKeyResponse structure from the expected dcerpc response' do
786
+ winreg.create_key(handle, sub_key)
787
+ expect(described_class::CreateKeyResponse).to have_received(:read).with(response)
788
+ end
789
+
790
+ context 'when an IOError occurs while parsing the response' do
791
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
792
+ allow(described_class::CreateKeyResponse).to receive(:read).and_raise(IOError)
793
+ expect { winreg.create_key(handle, sub_key) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
794
+ end
795
+ end
796
+
797
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
798
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
799
+ allow(create_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
800
+ expect { winreg.create_key(handle, sub_key) }.to raise_error(RubySMB::Dcerpc::Error::WinregError)
801
+ end
802
+ end
803
+
804
+ it 'returns the expected key name' do
805
+ expect(winreg.create_key(handle, sub_key)).to eq(hkey)
806
+ end
807
+ end
808
+
809
+ describe '#save_key' do
810
+ let(:handle) { double('Handle') }
811
+ let(:filename) { double('Filename') }
812
+ let(:save_key_request) { double('CreateKey Request') }
813
+ let(:response) { double('Response') }
814
+ let(:save_key_response) { double('CreateKey Response') }
815
+ let(:hkey) { double('hkey') }
816
+ before :example do
817
+ allow(described_class::SaveKeyRequest).to receive(:new).and_return(save_key_request)
818
+ allow(winreg).to receive(:dcerpc_request).and_return(response)
819
+ allow(described_class::SaveKeyResponse).to receive(:read).and_return(save_key_response)
820
+ allow(save_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
821
+ end
822
+
823
+ it 'create the expected SaveKeyRequest packet with the default options' do
824
+ opts = {
825
+ hkey: handle,
826
+ lp_file: filename,
827
+ lp_security_attributes: :null,
828
+ }
829
+ winreg.save_key(handle, filename)
830
+ expect(described_class::SaveKeyRequest).to have_received(:new).with(opts)
831
+ end
832
+
833
+ it 'create the expected SaveKeyRequest packet with custom options' do
834
+ opts = {
835
+ hkey: handle,
836
+ lp_file: filename,
837
+ lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new,
838
+ }
839
+ winreg.save_key(handle, filename, opts)
840
+ expect(described_class::SaveKeyRequest).to have_received(:new).with(opts)
841
+ end
842
+
843
+ it 'sends the expected dcerpc request' do
844
+ winreg.save_key(handle, filename)
845
+ expect(winreg).to have_received(:dcerpc_request).with(save_key_request)
846
+ end
847
+
848
+ it 'creates a SaveKeyResponse structure from the expected dcerpc response' do
849
+ winreg.save_key(handle, filename)
850
+ expect(described_class::SaveKeyResponse).to have_received(:read).with(response)
851
+ end
852
+
853
+ context 'when an IOError occurs while parsing the response' do
854
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
855
+ allow(described_class::SaveKeyResponse).to receive(:read).and_raise(IOError)
856
+ expect { winreg.save_key(handle, filename) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
857
+ end
858
+ end
859
+
860
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
861
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
862
+ allow(save_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
863
+ expect { winreg.save_key(handle, filename) }.to raise_error(RubySMB::Dcerpc::Error::WinregError)
864
+ end
865
+ end
866
+ end
710
867
  end
@@ -0,0 +1,43 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it 'is a Ndr::NdrWideStringPtr' do
5
+ expect(packet).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringPtr)
6
+ end
7
+ end
8
+
9
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::NetrWkstaGetInfoRequest do
10
+ subject(:packet) { described_class.new }
11
+
12
+ it { is_expected.to respond_to :server_name }
13
+ it { is_expected.to respond_to :level }
14
+ it { is_expected.to respond_to :opnum }
15
+
16
+ it 'is little endian' do
17
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
18
+ end
19
+ it 'is a BinData::Record' do
20
+ expect(packet).to be_a(BinData::Record)
21
+ end
22
+ describe '#server_name' do
23
+ it 'is a WkssvcIdentifyHandle structure' do
24
+ expect(packet.server_name).to be_a RubySMB::Dcerpc::Wkssvc::WkssvcIdentifyHandle
25
+ end
26
+ end
27
+ describe '#level' do
28
+ it 'is a NdrUint32 structure' do
29
+ expect(packet.level).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
30
+ end
31
+ end
32
+ describe '#initialize_instance' do
33
+ it 'sets #opnum to NETR_WKSTA_GET_INFO constant' do
34
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Wkssvc::NETR_WKSTA_GET_INFO)
35
+ end
36
+ end
37
+ it 'reads itself' do
38
+ new_class = described_class.new(server_name: 'TestServer', level: 4)
39
+ expect(packet.read(new_class.to_binary_s)).to eq(
40
+ {server_name: 'TestServer'.encode('utf-16le'), level: 4}
41
+ )
42
+ end
43
+ end