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
@@ -65,6 +65,8 @@ RSpec.describe RubySMB::Client do
65
65
  it { is_expected.to respond_to :verify_signature }
66
66
  it { is_expected.to respond_to :auth_user }
67
67
  it { is_expected.to respond_to :last_file_id }
68
+ it { is_expected.to respond_to :pid }
69
+ it { is_expected.to respond_to :server_supports_multi_credit }
68
70
 
69
71
  describe '#initialize' do
70
72
  it 'should raise an ArgumentError without a valid dispatcher' do
@@ -124,8 +126,7 @@ RSpec.describe RubySMB::Client do
124
126
  expect(password).to eq(password)
125
127
  expect(opt[:workstation]).to eq(local_workstation)
126
128
  expect(opt[:domain]).to eq(domain)
127
- flags = Net::NTLM::Client::DEFAULT_FLAGS |
128
- Net::NTLM::FLAGS[:TARGET_INFO] | 0x02000000 ^ Net::NTLM::FLAGS[:OEM]
129
+ flags = RubySMB::NTLM::DEFAULT_CLIENT_FLAGS
129
130
  expect(opt[:flags]).to eq(flags)
130
131
  end
131
132
 
@@ -141,6 +142,18 @@ RSpec.describe RubySMB::Client do
141
142
  it 'sets the max_buffer_size to MAX_BUFFER_SIZE' do
142
143
  expect(client.max_buffer_size).to eq RubySMB::Client::MAX_BUFFER_SIZE
143
144
  end
145
+
146
+ it 'sets the server_supports_multi_credit to false' do
147
+ expect(client.server_supports_multi_credit).to be false
148
+ end
149
+
150
+ it 'sets the pid to a random value' do
151
+ 100.times do
152
+ previous_pid = client.pid
153
+ client = described_class.new(dispatcher, username: username, password: password)
154
+ expect(client.pid).to_not eq(previous_pid)
155
+ end
156
+ end
144
157
  end
145
158
 
146
159
  describe '#echo' do
@@ -184,37 +197,38 @@ RSpec.describe RubySMB::Client do
184
197
  describe '#send_recv' do
185
198
  let(:smb1_request) { RubySMB::SMB1::Packet::TreeConnectRequest.new }
186
199
  let(:smb2_request) { RubySMB::SMB2::Packet::TreeConnectRequest.new }
200
+ let(:smb2_header) { RubySMB::SMB2::SMB2Header.new }
187
201
 
188
202
  before(:each) do
189
203
  allow(client).to receive(:is_status_pending?).and_return(false)
190
204
  allow(dispatcher).to receive(:send_packet).and_return(nil)
191
205
  allow(dispatcher).to receive(:recv_packet).and_return('A')
206
+ allow(RubySMB::SMB2::SMB2Header).to receive(:read).and_return(smb2_header)
192
207
  end
193
208
 
194
209
  context 'when signing' do
195
210
  it 'calls #smb1_sign if it is an SMB1 packet' do
211
+ allow(client).to receive(:signing_required).and_return(true)
212
+ allow(client).to receive(:session_key).and_return(Random.new.bytes(16))
196
213
  expect(client).to receive(:smb1_sign).with(smb1_request).and_call_original
197
214
  client.send_recv(smb1_request)
198
215
  end
199
216
 
200
217
  context 'with an SMB2 packet' do
201
218
  it 'does not sign a SessionSetupRequest packet' do
219
+ allow(smb2_client).to receive(:is_status_pending?).and_return(false)
202
220
  expect(smb2_client).to_not receive(:smb2_sign)
203
221
  expect(smb2_client).to_not receive(:smb3_sign)
204
- client.send_recv(RubySMB::SMB2::Packet::SessionSetupRequest.new)
222
+ smb2_client.send_recv(RubySMB::SMB2::Packet::SessionSetupRequest.new)
205
223
  end
206
224
 
207
225
  it 'calls #smb2_sign if it is an SMB2 client' do
208
226
  allow(smb2_client).to receive(:is_status_pending?).and_return(false)
227
+ allow(smb2_client).to receive(:signing_required).and_return(true)
228
+ allow(smb2_client).to receive(:session_key).and_return(Random.new.bytes(16))
209
229
  expect(smb2_client).to receive(:smb2_sign).with(smb2_request).and_call_original
210
230
  smb2_client.send_recv(smb2_request)
211
231
  end
212
-
213
- it 'calls #smb3_sign if it is an SMB3 client' do
214
- allow(smb3_client).to receive(:is_status_pending?).and_return(false)
215
- expect(smb3_client).to receive(:smb3_sign).with(smb2_request).and_call_original
216
- smb3_client.send_recv(smb2_request)
217
- end
218
232
  end
219
233
  end
220
234
 
@@ -229,6 +243,29 @@ RSpec.describe RubySMB::Client do
229
243
  expect(smb1_client).to_not receive(:is_status_pending?)
230
244
  smb1_client.send_recv(smb1_request)
231
245
  end
246
+
247
+ it 'set the #uid SMB header when #user_id is defined' do
248
+ smb1_client.user_id = 333
249
+ smb1_client.send_recv(smb1_request)
250
+ expect(smb1_request.smb_header.uid).to eq(333)
251
+ end
252
+
253
+ it 'does not set the #uid SMB header when #user_id is not defined' do
254
+ smb1_client.send_recv(smb1_request)
255
+ expect(smb1_request.smb_header.uid).to eq(0)
256
+ end
257
+
258
+ it 'set the #pid SMB header when #pid is defined' do
259
+ smb1_client.pid = 333
260
+ smb1_client.send_recv(smb1_request)
261
+ expect(smb1_request.smb_header.pid_low).to eq(333)
262
+ end
263
+
264
+ it 'does not set the #pid SMB header when #pid is not defined' do
265
+ smb1_client.pid = nil
266
+ smb1_client.send_recv(smb1_request)
267
+ expect(smb1_request.smb_header.pid_low).to eq(0)
268
+ end
232
269
  end
233
270
 
234
271
  context 'with SMB2' do
@@ -251,10 +288,8 @@ RSpec.describe RubySMB::Client do
251
288
  context 'with a SessionSetupRequest' do
252
289
  it 'does not encrypt/decrypt' do
253
290
  request = RubySMB::SMB2::Packet::SessionSetupRequest.new
254
- expect(smb3_client).to_not receive(:send_encrypt).with(request)
255
- expect(smb3_client).to_not receive(:recv_encrypt)
256
- expect(dispatcher).to receive(:send_packet).with(request)
257
- expect(dispatcher).to receive(:recv_packet)
291
+ expect(smb3_client).to receive(:send_packet).with(request, encrypt: false)
292
+ expect(smb3_client).to receive(:recv_packet).with(encrypt: false)
258
293
  smb3_client.send_recv(request)
259
294
  end
260
295
  end
@@ -262,17 +297,15 @@ RSpec.describe RubySMB::Client do
262
297
  context 'with a NegotiateRequest' do
263
298
  it 'does not encrypt/decrypt' do
264
299
  request = RubySMB::SMB2::Packet::NegotiateRequest.new
265
- expect(smb3_client).to_not receive(:send_encrypt).with(request)
266
- expect(smb3_client).to_not receive(:recv_encrypt)
267
- expect(dispatcher).to receive(:send_packet).with(request)
268
- expect(dispatcher).to receive(:recv_packet)
300
+ expect(smb3_client).to receive(:send_packet).with(request, encrypt: false)
301
+ expect(smb3_client).to receive(:recv_packet).with(encrypt: false)
269
302
  smb3_client.send_recv(request)
270
303
  end
271
304
  end
272
305
 
273
306
  it 'encrypts and decrypts' do
274
- expect(smb3_client).to receive(:send_encrypt).with(smb2_request)
275
- expect(smb3_client).to receive(:recv_encrypt)
307
+ expect(smb3_client).to receive(:send_packet).with(smb2_request, encrypt: true)
308
+ expect(smb3_client).to receive(:recv_packet).with(encrypt: true)
276
309
  smb3_client.send_recv(smb2_request)
277
310
  end
278
311
 
@@ -280,12 +313,44 @@ RSpec.describe RubySMB::Client do
280
313
  it 'waits 1 second and reads/decrypts again' do
281
314
  allow(smb3_client).to receive(:is_status_pending?).and_return(true, false)
282
315
  expect(smb3_client).to receive(:sleep).with(1)
283
- expect(smb3_client).to receive(:send_encrypt).with(smb2_request)
284
- expect(smb3_client).to receive(:recv_encrypt).twice
316
+ expect(smb3_client).to receive(:send_packet).with(smb2_request, encrypt: true)
317
+ expect(smb3_client).to receive(:recv_packet).with(encrypt: true).twice
285
318
  smb3_client.send_recv(smb2_request)
286
319
  end
287
320
  end
288
321
  end
322
+
323
+ it 'increments the sequence counter if signing is required and the session key exist' do
324
+ allow(smb2_client).to receive(:is_status_pending?).and_return(false)
325
+ smb2_client.signing_required = true
326
+ smb2_client.session_key = 'key'
327
+ smb2_client.sequence_counter = 0
328
+ smb2_client.send_recv(smb2_request)
329
+ expect(smb2_client.sequence_counter).to eq(1)
330
+ end
331
+
332
+ it 'updates #smb2_message_id with SMB2 header #credit_charge if the server supports multi credits' do
333
+ allow(smb2_client).to receive(:is_status_pending?).and_return(false)
334
+ smb2_client.smb2_message_id = 0
335
+ smb2_client.server_supports_multi_credit = true
336
+ smb2_header.credit_charge = 5
337
+ smb2_client.send_recv(smb2_request)
338
+ expect(smb2_client.smb2_message_id).to eq(5)
339
+ end
340
+
341
+ it 'does not update #msb2_message_id with SMB2 header #credit_charge if the server does not support multi credits' do
342
+ allow(smb2_client).to receive(:is_status_pending?).and_return(false)
343
+ smb2_client.smb2_message_id = 0
344
+ smb2_client.server_supports_multi_credit = false
345
+ smb2_header.credit_charge = 5
346
+ smb2_client.send_recv(smb2_request)
347
+ expect(smb2_client.smb2_message_id).to eq(1)
348
+ end
349
+
350
+ it 'ignores errors thrown when parsing the SMB2 header' do
351
+ allow(RubySMB::SMB2::SMB2Header).to receive(:read).and_raise(IOError)
352
+ expect { smb2_client.send_recv(smb2_request) }.to_not raise_error
353
+ end
289
354
  end
290
355
 
291
356
  describe '#is_status_pending?' do
@@ -297,17 +362,17 @@ RSpec.describe RubySMB::Client do
297
362
  }
298
363
 
299
364
  it 'returns true when the response has a STATUS_PENDING status code and the async_command flag set' do
300
- expect(client.is_status_pending?(response.to_binary_s)).to be true
365
+ expect(client.is_status_pending?(response.smb2_header)).to be true
301
366
  end
302
367
 
303
368
  it 'returns false when the response has a STATUS_PENDING status code and the async_command flag not set' do
304
369
  response.smb2_header.flags.async_command = 0
305
- expect(client.is_status_pending?(response.to_binary_s)).to be false
370
+ expect(client.is_status_pending?(response.smb2_header)).to be false
306
371
  end
307
372
 
308
373
  it 'returns false when the response has no STATUS_PENDING status code but the async_command flag set' do
309
374
  response.smb2_header.nt_status= WindowsError::NTStatus::STATUS_SUCCESS.value
310
- expect(client.is_status_pending?(response.to_binary_s)).to be false
375
+ expect(client.is_status_pending?(response.smb2_header)).to be false
311
376
  end
312
377
  end
313
378
 
@@ -344,35 +409,47 @@ RSpec.describe RubySMB::Client do
344
409
  end
345
410
  end
346
411
 
347
- describe '#send_encrypt' do
412
+ describe '#send_packet' do
348
413
  let(:packet) { RubySMB::SMB2::Packet::SessionSetupRequest.new }
349
414
  before :example do
350
415
  allow(dispatcher).to receive(:send_packet)
351
416
  client.dialect = '0x0300'
352
417
  end
353
418
 
354
- it 'creates a Transform request' do
355
- expect(client).to receive(:smb3_encrypt).with(packet.to_binary_s)
356
- client.send_encrypt(packet)
419
+ it 'does not encrypt the packet' do
420
+ expect(client).to_not receive(:smb3_encrypt)
421
+ client.send_packet(packet)
357
422
  end
358
423
 
359
- it 'raises an EncryptionError exception if an error occurs while encrypting' do
360
- allow(client).to receive(:smb3_encrypt).and_raise(RubySMB::Error::RubySMBError.new('Error'))
361
- expect { client.send_encrypt(packet) }.to raise_error(
362
- RubySMB::Error::EncryptionError,
363
- "Error while encrypting #{packet.class.name} packet (SMB 0x0300): Error"
364
- )
424
+ it 'sends the packet through the dispatcher' do
425
+ client.send_packet(packet)
426
+ expect(dispatcher).to have_received(:send_packet).with(packet)
365
427
  end
366
428
 
367
- it 'sends the encrypted packet' do
368
- encrypted_packet = double('Encrypted packet')
369
- allow(client).to receive(:smb3_encrypt).and_return(encrypted_packet)
370
- client.send_encrypt(packet)
371
- expect(dispatcher).to have_received(:send_packet).with(encrypted_packet)
429
+ context 'with encryption' do
430
+ it 'creates a Transform request' do
431
+ expect(client).to receive(:smb3_encrypt).with(packet.to_binary_s)
432
+ client.send_packet(packet, encrypt: true)
433
+ end
434
+
435
+ it 'raises an EncryptionError exception if an error occurs while encrypting' do
436
+ allow(client).to receive(:smb3_encrypt).and_raise(RubySMB::Error::RubySMBError.new('Error'))
437
+ expect { client.send_packet(packet, encrypt: true) }.to raise_error(
438
+ RubySMB::Error::EncryptionError,
439
+ "Error while encrypting #{packet.class.name} packet (SMB 0x0300): Error"
440
+ )
441
+ end
442
+
443
+ it 'sends the encrypted packet' do
444
+ encrypted_packet = double('Encrypted packet')
445
+ allow(client).to receive(:smb3_encrypt).and_return(encrypted_packet)
446
+ client.send_packet(packet, encrypt: true)
447
+ expect(dispatcher).to have_received(:send_packet).with(encrypted_packet)
448
+ end
372
449
  end
373
450
  end
374
451
 
375
- describe '#recv_encrypt' do
452
+ describe '#recv_packet' do
376
453
  let(:packet) { RubySMB::SMB2::Packet::SessionSetupRequest.new }
377
454
  before :example do
378
455
  allow(dispatcher).to receive(:recv_packet).and_return(packet.to_binary_s)
@@ -381,42 +458,49 @@ RSpec.describe RubySMB::Client do
381
458
  end
382
459
 
383
460
  it 'reads the response packet' do
384
- client.recv_encrypt
461
+ client.recv_packet
385
462
  expect(dispatcher).to have_received(:recv_packet)
386
463
  end
387
464
 
388
- it 'raises an EncryptionError exception if an error occurs while receiving the response' do
465
+ it 'raises an CommunicationError exception if an error occurs while receiving the response' do
389
466
  allow(dispatcher).to receive(:recv_packet).and_raise(RubySMB::Error::CommunicationError)
390
- expect { client.recv_encrypt }.to raise_error(
391
- RubySMB::Error::EncryptionError,
392
- 'Communication error with the remote host: RubySMB::Error::CommunicationError. '\
393
- 'The server supports encryption but was not able to handle the encrypted request.'
394
- )
467
+ expect { client.recv_packet }.to raise_error(RubySMB::Error::CommunicationError)
395
468
  end
396
469
 
397
- it 'parses the response as a Transform response packet' do
398
- expect(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).with(packet.to_binary_s)
399
- client.recv_encrypt
400
- end
470
+ context 'with encryption' do
471
+ it 'raises an EncryptionError exception if an error occurs while receiving the response' do
472
+ allow(dispatcher).to receive(:recv_packet).and_raise(RubySMB::Error::CommunicationError)
473
+ expect { client.recv_packet(encrypt: true) }.to raise_error(
474
+ RubySMB::Error::EncryptionError,
475
+ 'Communication error with the remote host: RubySMB::Error::CommunicationError. '\
476
+ 'The server supports encryption but was not able to handle the encrypted request.'
477
+ )
478
+ end
401
479
 
402
- it 'raises an InvalidPacket exception if an error occurs while parsing the response' do
403
- allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_raise(IOError)
404
- expect { client.recv_encrypt }.to raise_error(RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet')
405
- end
480
+ it 'parses the response as a Transform response packet' do
481
+ expect(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).with(packet.to_binary_s)
482
+ client.recv_packet(encrypt: true)
483
+ end
406
484
 
407
- it 'decrypts the Transform response packet' do
408
- transform = double('Transform header packet')
409
- allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_return(transform)
410
- client.recv_encrypt
411
- expect(client).to have_received(:smb3_decrypt).with(transform)
412
- end
485
+ it 'raises an InvalidPacket exception if an error occurs while parsing the response' do
486
+ allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_raise(IOError)
487
+ expect { client.recv_packet(encrypt: true) }.to raise_error(RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet')
488
+ end
413
489
 
414
- it 'raises an EncryptionError exception if an error occurs while decrypting' do
415
- allow(client).to receive(:smb3_decrypt).and_raise(RubySMB::Error::RubySMBError)
416
- expect { client.recv_encrypt }.to raise_error(
417
- RubySMB::Error::EncryptionError,
418
- 'Error while decrypting RubySMB::SMB2::Packet::TransformHeader packet (SMB 0x0300}): RubySMB::Error::RubySMBError'
419
- )
490
+ it 'decrypts the Transform response packet' do
491
+ transform = double('Transform header packet')
492
+ allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_return(transform)
493
+ client.recv_packet(encrypt: true)
494
+ expect(client).to have_received(:smb3_decrypt).with(transform)
495
+ end
496
+
497
+ it 'raises an EncryptionError exception if an error occurs while decrypting' do
498
+ allow(client).to receive(:smb3_decrypt).and_raise(RubySMB::Error::RubySMBError)
499
+ expect { client.recv_packet(encrypt: true) }.to raise_error(
500
+ RubySMB::Error::EncryptionError,
501
+ 'Error while decrypting RubySMB::SMB2::Packet::TransformHeader packet (SMB 0x0300}): RubySMB::Error::RubySMBError'
502
+ )
503
+ end
420
504
  end
421
505
  end
422
506
 
@@ -667,7 +751,7 @@ RSpec.describe RubySMB::Client do
667
751
  expect(session_packet.session_header.session_packet_type).to eq RubySMB::Nbss::SESSION_REQUEST
668
752
  expect(session_packet.called_name).to eq called_name
669
753
  expect(session_packet.calling_name).to eq calling_name
670
- expect(session_packet.session_header.packet_length).to eq(
754
+ expect(session_packet.session_header.stream_protocol_length).to eq(
671
755
  session_packet.called_name.to_binary_s.size + session_packet.calling_name.to_binary_s.size
672
756
  )
673
757
  end
@@ -722,6 +806,18 @@ RSpec.describe RubySMB::Client do
722
806
  smb1_extended_response.to_binary_s
723
807
  }
724
808
 
809
+ let(:smb1_response) {
810
+ packet = RubySMB::SMB1::Packet::NegotiateResponse.new
811
+ smb1_capabilities_dup = smb1_capabilities.dup
812
+ smb1_capabilities_dup[:extended_security] = 0
813
+
814
+ packet.parameter_block.capabilities = smb1_capabilities_dup
815
+ packet
816
+ }
817
+ let(:smb1_response_raw) {
818
+ smb1_response.to_binary_s
819
+ }
820
+
725
821
  let(:smb2_response) { RubySMB::SMB2::Packet::NegotiateResponse.new(dialect_revision: 0x200) }
726
822
  let(:smb3_response) { RubySMB::SMB2::Packet::NegotiateResponse.new(dialect_revision: 0x300) }
727
823
 
@@ -910,10 +1006,14 @@ RSpec.describe RubySMB::Client do
910
1006
 
911
1007
  describe '#negotiate_response' do
912
1008
  context 'with only SMB1' do
913
- it 'returns a properly formed packet' do
1009
+ it 'returns a properly formed NegotiateResponseExtended packet if extended_security is set as 1' do
914
1010
  expect(smb1_client.negotiate_response(smb1_extended_response_raw)).to eq smb1_extended_response
915
1011
  end
916
1012
 
1013
+ it 'returns a properly formed NegotiateResponse packet if extended_security is set as 0' do
1014
+ expect(smb1_client.negotiate_response(smb1_response_raw)).to eq smb1_response
1015
+ end
1016
+
917
1017
  it 'raises an exception if the response is not a SMB packet' do
918
1018
  expect { smb1_client.negotiate_response(random_junk) }.to raise_error(RubySMB::Error::InvalidPacket)
919
1019
  end
@@ -928,12 +1028,6 @@ RSpec.describe RubySMB::Client do
928
1028
  bogus_response.smb_header.command = 0xff
929
1029
  expect { smb1_client.negotiate_response(bogus_response.to_binary_s) }.to raise_error(RubySMB::Error::InvalidPacket)
930
1030
  end
931
-
932
- it 'considers the response invalid if Extended Security is not enabled' do
933
- bogus_response = smb1_extended_response
934
- bogus_response.parameter_block.capabilities.extended_security = 0
935
- expect { smb1_client.negotiate_response(bogus_response.to_binary_s) }.to raise_error(RubySMB::Error::InvalidPacket)
936
- end
937
1031
  end
938
1032
 
939
1033
  context 'with only SMB2' do
@@ -1036,6 +1130,19 @@ RSpec.describe RubySMB::Client do
1036
1130
  it 'returns the string \'SMB2\'' do
1037
1131
  expect(client.parse_negotiate_response(smb2_response)).to eq ('SMB2')
1038
1132
  end
1133
+
1134
+ it 'sets #server_supports_multi_credit to true when the response has #large_mtu capability set' do
1135
+ smb2_response.capabilities.large_mtu = 1
1136
+ client.parse_negotiate_response(smb2_response)
1137
+ expect(client.server_supports_multi_credit).to be true
1138
+ end
1139
+
1140
+ it 'sets #server_supports_multi_credit to false when the dialect is 0x0202' do
1141
+ smb2_response.dialect_revision = 0x0202
1142
+ smb2_response.capabilities.large_mtu = 1 # just to make sure it won't affect the result
1143
+ client.parse_negotiate_response(smb2_response)
1144
+ expect(client.server_supports_multi_credit).to be false
1145
+ end
1039
1146
  end
1040
1147
 
1041
1148
  context 'when SMB3 was negotiated' do
@@ -1060,6 +1167,12 @@ RSpec.describe RubySMB::Client do
1060
1167
  expect(client.parse_negotiate_response(smb3_response)).to eq ('SMB3')
1061
1168
  end
1062
1169
 
1170
+ it 'sets #server_supports_multi_credit to true when the response has #large_mtu capability set' do
1171
+ smb3_response.capabilities.large_mtu = 1
1172
+ client.parse_negotiate_response(smb3_response)
1173
+ expect(client.server_supports_multi_credit).to be true
1174
+ end
1175
+
1063
1176
  context 'when the server supports encryption' do
1064
1177
  before :example do
1065
1178
  smb3_response.capabilities.encryption = 1
@@ -1971,7 +2084,7 @@ RSpec.describe RubySMB::Client do
1971
2084
  it 'generates the HMAC based on the packet and the NTLM session key and signs the packet with it' do
1972
2085
  smb2_client.session_key = 'foo'
1973
2086
  smb2_client.signing_required = true
1974
- expect(OpenSSL::HMAC).to receive(:digest).with(instance_of(OpenSSL::Digest::SHA256), smb2_client.session_key, request1.to_binary_s).and_return(fake_hmac)
2087
+ expect(OpenSSL::HMAC).to receive(:digest).with(instance_of(OpenSSL::Digest), smb2_client.session_key, request1.to_binary_s).and_return(fake_hmac)
1975
2088
  expect(smb2_client.smb2_sign(request1).smb2_header.signature).to eq fake_hmac
1976
2089
  end
1977
2090
  end
@@ -2071,7 +2184,7 @@ RSpec.describe RubySMB::Client do
2071
2184
  smb3_client.dialect = '0x0202'
2072
2185
  expect { smb3_client.smb3_sign(request) }.to raise_error(
2073
2186
  RubySMB::Error::SigningError,
2074
- 'Dialect is incompatible with SMBv3 signing'
2187
+ 'Dialect "0x0202" is incompatible with SMBv3 signing'
2075
2188
  )
2076
2189
  end
2077
2190
  end
@@ -2121,7 +2234,7 @@ RSpec.describe RubySMB::Client do
2121
2234
  smb3_client.dialect = '0x0202'
2122
2235
  expect { smb3_client.smb3_sign(request) }.to raise_error(
2123
2236
  RubySMB::Error::SigningError,
2124
- 'Dialect is incompatible with SMBv3 signing'
2237
+ 'Dialect "0x0202" is incompatible with SMBv3 signing'
2125
2238
  )
2126
2239
  end
2127
2240
  end
@@ -2253,7 +2366,7 @@ RSpec.describe RubySMB::Client do
2253
2366
  let(:named_pipe){ double("Named Pipe") }
2254
2367
 
2255
2368
  before :example do
2256
- allow(tree).to receive(:open_file).and_return(named_pipe)
2369
+ allow(tree).to receive(:open_pipe).and_return(named_pipe)
2257
2370
  allow(named_pipe).to receive(:net_share_enum_all)
2258
2371
  end
2259
2372
 
@@ -2268,8 +2381,8 @@ RSpec.describe RubySMB::Client do
2268
2381
  smb1_client.net_share_enum_all(sock.peeraddr)
2269
2382
  end
2270
2383
 
2271
- it 'it calls the Tree #open_file method to open "srvsvc" named pipe' do
2272
- expect(tree).to receive(:open_file).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2384
+ it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
2385
+ expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2273
2386
  smb1_client.net_share_enum_all(sock.peeraddr)
2274
2387
  end
2275
2388
 
@@ -2291,8 +2404,8 @@ RSpec.describe RubySMB::Client do
2291
2404
  smb2_client.net_share_enum_all(sock.peeraddr)
2292
2405
  end
2293
2406
 
2294
- it 'it calls the Tree #open_file method to open "srvsvc" named pipe' do
2295
- expect(tree).to receive(:open_file).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2407
+ it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
2408
+ expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
2296
2409
  smb2_client.net_share_enum_all(sock.peeraddr)
2297
2410
  end
2298
2411
 
@@ -2373,7 +2486,7 @@ RSpec.describe RubySMB::Client do
2373
2486
  before :example do
2374
2487
  allow(ipc_tree).to receive_messages(
2375
2488
  :share => share,
2376
- :open_file => named_pipe
2489
+ :open_pipe => named_pipe
2377
2490
  )
2378
2491
  allow(client).to receive(:tree_connect).and_return(ipc_tree)
2379
2492
  end
@@ -2395,9 +2508,9 @@ RSpec.describe RubySMB::Client do
2395
2508
  expect(client).to have_received(:tree_connect).with(share)
2396
2509
  end
2397
2510
 
2398
- it 'open \'winreg\' file on the IPC$ Tree' do
2511
+ it 'open \'winreg\' pipe on the IPC$ Tree' do
2399
2512
  client.connect_to_winreg(host)
2400
- expect(ipc_tree).to have_received(:open_file).with(filename: "winreg", write: true, read: true)
2513
+ expect(ipc_tree).to have_received(:open_pipe).with(filename: "winreg", write: true, read: true)
2401
2514
  end
2402
2515
 
2403
2516
  it 'returns the expected opened named pipe' do
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Compression::LZNT1 do
4
+ describe '.compress' do
5
+ it 'generates an empty blob when provided an empty blob' do
6
+ expected = "".b
7
+ expect(described_class.compress('')).to eq(expected)
8
+ end
9
+
10
+ it 'generates a compressed blob when provided a string with non-reoccurring characters' do
11
+ expect(described_class.compress('RubySMB')).to eq("\x060RubySMB".b)
12
+ end
13
+
14
+ it 'generates a compressed blob when provided a string of reoccurring characters' do
15
+ expect(described_class.compress("\x01" * 0x200)).to eq("\x03\xB0\x02\x01\xFC\x01".b)
16
+ end
17
+ end
18
+
19
+ describe '.decompress' do
20
+ it 'generates a decompressed blob for a string with non-reoccurring characters' do
21
+ expect(described_class.decompress("\x060RubySMB".b)).to eq('RubySMB')
22
+ end
23
+
24
+ it 'generates a decompressed blob for a string of reoccurring characters' do
25
+ expect(described_class.decompress("\x03\xB0\x02\x01\xFC\x01".b)).to eq("\x01" * 0x200)
26
+ end
27
+
28
+ it 'raises an EncodingError when the length is invalid' do
29
+ expect { described_class.decompress("\x010".b) }.to raise_error(EncodingError)
30
+ end
31
+ end
32
+ end