ruby_smb 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +46 -0
  4. data/README.md +0 -1
  5. data/examples/anonymous_auth.rb +3 -3
  6. data/examples/append_file.rb +10 -8
  7. data/examples/auth_capture.rb +71 -0
  8. data/examples/authenticate.rb +9 -5
  9. data/examples/delete_file.rb +8 -6
  10. data/examples/dump_secrets_from_sid.rb +207 -0
  11. data/examples/enum_domain_users.rb +75 -0
  12. data/examples/enum_registry_key.rb +5 -4
  13. data/examples/enum_registry_values.rb +5 -4
  14. data/examples/get_computer_info.rb +42 -0
  15. data/examples/list_directory.rb +8 -6
  16. data/examples/negotiate_with_netbios_service.rb +9 -5
  17. data/examples/net_share_enum_all.rb +6 -4
  18. data/examples/pipes.rb +11 -12
  19. data/examples/query_service_status.rb +102 -0
  20. data/examples/read_file.rb +8 -6
  21. data/examples/read_registry_key_value.rb +6 -5
  22. data/examples/rename_file.rb +9 -7
  23. data/examples/tree_connect.rb +7 -5
  24. data/examples/write_file.rb +9 -7
  25. data/lib/ruby_smb/client/authentication.rb +5 -10
  26. data/lib/ruby_smb/client/echo.rb +2 -4
  27. data/lib/ruby_smb/client/negotiation.rb +13 -16
  28. data/lib/ruby_smb/client/tree_connect.rb +2 -4
  29. data/lib/ruby_smb/client/utils.rb +16 -10
  30. data/lib/ruby_smb/client/winreg.rb +1 -1
  31. data/lib/ruby_smb/client.rb +102 -75
  32. data/lib/ruby_smb/compression/lznt1.rb +164 -0
  33. data/lib/ruby_smb/compression.rb +7 -0
  34. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  35. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  36. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  37. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  38. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  39. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  40. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  41. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  42. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  43. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  44. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  45. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  46. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  47. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  48. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  49. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  50. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  51. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  52. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  53. data/lib/ruby_smb/dcerpc/error.rb +20 -0
  54. data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
  55. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
  56. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
  57. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
  58. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
  59. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
  61. data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
  62. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  63. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  64. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  65. data/lib/ruby_smb/dcerpc/request.rb +85 -19
  66. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  67. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  68. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
  69. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  70. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  79. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  80. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  81. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  82. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  83. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  84. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  85. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  86. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  87. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  88. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  89. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  90. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  91. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  92. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  93. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +36 -0
  94. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
  95. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
  96. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
  97. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
  98. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
  99. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
  100. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
  101. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
  102. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
  103. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
  104. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
  105. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
  106. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
  107. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
  108. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
  109. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
  110. data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
  111. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  112. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  113. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +62 -0
  114. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
  115. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
  116. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  117. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  118. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  119. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  120. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  121. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +6 -7
  122. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  123. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
  124. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  125. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
  126. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  127. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  128. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +28 -0
  129. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
  130. data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
  131. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  132. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  133. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  134. data/lib/ruby_smb/dcerpc.rb +45 -11
  135. data/lib/ruby_smb/dialect.rb +45 -0
  136. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  137. data/lib/ruby_smb/dispatcher/socket.rb +2 -2
  138. data/lib/ruby_smb/error.rb +21 -5
  139. data/lib/ruby_smb/field/file_time.rb +1 -1
  140. data/lib/ruby_smb/field/string16.rb +5 -1
  141. data/lib/ruby_smb/field/stringz16.rb +17 -1
  142. data/lib/ruby_smb/generic_packet.rb +11 -1
  143. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  144. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  145. data/lib/ruby_smb/gss/provider.rb +35 -0
  146. data/lib/ruby_smb/gss.rb +56 -63
  147. data/lib/ruby_smb/nbss/session_header.rb +4 -4
  148. data/lib/ruby_smb/ntlm.rb +61 -0
  149. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  150. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  151. data/lib/ruby_smb/server/server_client.rb +162 -0
  152. data/lib/ruby_smb/server.rb +54 -0
  153. data/lib/ruby_smb/signing.rb +59 -0
  154. data/lib/ruby_smb/smb1/file.rb +10 -25
  155. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  156. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  157. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  158. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
  159. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
  160. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
  161. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
  162. data/lib/ruby_smb/smb1/pipe.rb +12 -6
  163. data/lib/ruby_smb/smb1/tree.rb +13 -9
  164. data/lib/ruby_smb/smb2/file.rb +33 -33
  165. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  166. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
  167. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  168. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  169. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  170. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  171. data/lib/ruby_smb/smb2/pipe.rb +13 -6
  172. data/lib/ruby_smb/smb2/tree.rb +21 -11
  173. data/lib/ruby_smb/smb2.rb +3 -1
  174. data/lib/ruby_smb/version.rb +1 -1
  175. data/lib/ruby_smb.rb +5 -3
  176. data/spec/lib/ruby_smb/client_spec.rb +199 -86
  177. data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
  178. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  179. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  180. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  181. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3977 -239
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
  187. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
  188. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
  189. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  190. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  191. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  192. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  193. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  194. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +162 -0
  195. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  196. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  197. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  198. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  199. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  200. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  201. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  210. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  211. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  212. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  213. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +168 -0
  214. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
  215. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
  216. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
  217. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
  218. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
  230. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
  231. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  232. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  233. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +73 -0
  234. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
  235. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
  236. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  237. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  238. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  239. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  240. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  241. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -20
  242. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  243. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
  244. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  245. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  246. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +18 -42
  247. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  248. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
  249. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
  250. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
  251. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  252. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  253. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  254. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
  255. data/spec/lib/ruby_smb/error_spec.rb +34 -5
  256. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  257. data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
  258. data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  261. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  262. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  263. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
  264. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  265. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  266. data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
  267. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
  268. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
  269. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
  270. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
  271. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
  272. data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
  273. data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
  274. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  275. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
  276. data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
  277. data/spec/spec_helper.rb +1 -1
  278. data/spec/support/bin_helper.rb +9 -0
  279. data.tar.gz.sig +0 -0
  280. metadata +229 -23
  281. metadata.gz.sig +0 -0
  282. data/.travis.yml +0 -6
  283. data/lib/ruby_smb/client/signing.rb +0 -64
  284. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
  285. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
@@ -0,0 +1,156 @@
1
+ require 'securerandom'
2
+
3
+ module RubySMB
4
+ class Server
5
+ class ServerClient
6
+ module Negotiation
7
+ #
8
+ # Handle an SMB negotiation request. Once negotiation is complete, the state will be updated to :session_setup.
9
+ # At this point the @dialect will have been set along with other dialect-specific values.
10
+ #
11
+ # @param [String] raw_request the negotiation request to process
12
+ def handle_negotiate(raw_request)
13
+ response = nil
14
+ case raw_request[0...4].unpack1('L>')
15
+ when RubySMB::SMB1::SMB_PROTOCOL_ID
16
+ request = SMB1::Packet::NegotiateRequest.read(raw_request)
17
+ response = do_negotiate_smb1(request) if request.is_a?(SMB1::Packet::NegotiateRequest)
18
+ when RubySMB::SMB2::SMB2_PROTOCOL_ID
19
+ request = SMB2::Packet::NegotiateRequest.read(raw_request)
20
+ response = do_negotiate_smb2(request) if request.is_a?(SMB2::Packet::NegotiateRequest)
21
+ end
22
+
23
+ if response.nil?
24
+ disconnect!
25
+ else
26
+ send_packet(response)
27
+ end
28
+
29
+ nil
30
+ end
31
+
32
+ def do_negotiate_smb1(request)
33
+ client_dialects = request.dialects.map(&:dialect_string).map(&:value)
34
+
35
+ if client_dialects.include?(Client::SMB1_DIALECT_SMB2_WILDCARD) && \
36
+ @server.dialects.any? { |dialect| Dialect[dialect].order == Dialect::ORDER_SMB2 }
37
+ response = SMB2::Packet::NegotiateResponse.new
38
+ response.smb2_header.credits = 1
39
+ response.security_mode.signing_enabled = 1
40
+ response.dialect_revision = SMB2::SMB2_WILDCARD_REVISION
41
+ response.server_guid = @server.guid
42
+
43
+ response.max_transact_size = 0x800000
44
+ response.max_read_size = 0x800000
45
+ response.max_write_size = 0x800000
46
+ response.system_time.set(Time.now)
47
+ response.security_buffer_offset = response.security_buffer.abs_offset
48
+ response.security_buffer = process_gss.buffer
49
+ return response
50
+ end
51
+
52
+ server_dialects = @server.dialects.select { |dialect| Dialect[dialect].order == Dialect::ORDER_SMB1 }
53
+ dialect = (server_dialects & client_dialects).first
54
+ if dialect.nil?
55
+ # 'NT LM 0.12' is currently the only supported dialect
56
+ # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/80850595-e301-4464-9745-58e4945eb99b
57
+ response = SMB1::Packet::NegotiateResponse.new
58
+ response.parameter_block.word_count = 1
59
+ response.parameter_block.dialect_index = 0xffff
60
+ response.data_block.byte_count = 0
61
+ return response
62
+ end
63
+
64
+ response = SMB1::Packet::NegotiateResponseExtended.new
65
+ response.parameter_block.dialect_index = client_dialects.index(dialect)
66
+ response.parameter_block.max_mpx_count = 50
67
+ response.parameter_block.max_number_vcs = 1
68
+ response.parameter_block.max_buffer_size = 16644
69
+ response.parameter_block.max_raw_size = 65536
70
+ server_time = Time.now
71
+ response.parameter_block.system_time.set(server_time)
72
+ response.parameter_block.server_time_zone = server_time.utc_offset
73
+ response.data_block.server_guid = @server.guid
74
+ response.data_block.security_blob = process_gss.buffer
75
+
76
+ @state = :session_setup
77
+ @dialect = dialect
78
+ response
79
+ end
80
+
81
+ def do_negotiate_smb2(request)
82
+ client_dialects = request.dialects.map { |d| "0x%04x" % d }
83
+ server_dialects = @server.dialects.select { |dialect| Dialect[dialect].order == Dialect::ORDER_SMB2 }
84
+ dialect = (server_dialects & client_dialects).first
85
+
86
+ response = SMB2::Packet::NegotiateResponse.new
87
+ response.smb2_header.credits = 1
88
+ response.smb2_header.message_id = request.smb2_header.message_id
89
+ response.security_mode.signing_enabled = 1
90
+ response.server_guid = @server.guid
91
+ response.max_transact_size = 0x800000
92
+ response.max_read_size = 0x800000
93
+ response.max_write_size = 0x800000
94
+ response.system_time.set(Time.now)
95
+ if dialect.nil?
96
+ # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/b39f253e-4963-40df-8dff-2f9040ebbeb1
97
+ # > If a common dialect is not found, the server MUST fail the request with STATUS_NOT_SUPPORTED.
98
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NOT_SUPPORTED.value
99
+ return response
100
+ end
101
+
102
+ contexts = []
103
+ hash_algorithm = hash_value = nil
104
+ if dialect == '0x0311'
105
+ # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/b39f253e-4963-40df-8dff-2f9040ebbeb1
106
+ nc = request.find_negotiate_context(SMB2::NegotiateContext::SMB2_PREAUTH_INTEGRITY_CAPABILITIES)
107
+ hash_algorithm = SMB2::PreauthIntegrityCapabilities::HASH_ALGORITM_MAP[nc&.data&.hash_algorithms&.first]
108
+ hash_value = "\x00" * 64
109
+ unless hash_algorithm
110
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_PARAMETER.value
111
+ return response
112
+ end
113
+
114
+ contexts << SMB2::NegotiateContext.new(
115
+ context_type: SMB2::NegotiateContext::SMB2_PREAUTH_INTEGRITY_CAPABILITIES,
116
+ data: {
117
+ hash_algorithms: [ SMB2::PreauthIntegrityCapabilities::SHA_512 ],
118
+ salt: SecureRandom.random_bytes(32)
119
+ }
120
+ )
121
+
122
+ nc = request.find_negotiate_context(SMB2::NegotiateContext::SMB2_ENCRYPTION_CAPABILITIES)
123
+ cipher = nc&.data&.ciphers&.first
124
+ cipher = 0 unless SMB2::EncryptionCapabilities::ENCRYPTION_ALGORITHM_MAP.include? cipher
125
+ contexts << SMB2::NegotiateContext.new(
126
+ context_type: SMB2::NegotiateContext::SMB2_ENCRYPTION_CAPABILITIES,
127
+ data: {
128
+ ciphers: [ cipher ]
129
+ }
130
+ )
131
+ end
132
+
133
+ # the order in which the response is built is important to ensure it is valid
134
+ response.dialect_revision = dialect.to_i(16)
135
+ response.security_buffer_offset = response.security_buffer.abs_offset
136
+ response.security_buffer = process_gss.buffer
137
+ if dialect == '0x0311'
138
+ response.negotiate_context_offset = response.negotiate_context_list.abs_offset
139
+ contexts.each { |nc| response.add_negotiate_context(nc) }
140
+ end
141
+ @preauth_integrity_hash_algorithm = hash_algorithm
142
+ @preauth_integrity_hash_value = hash_value
143
+
144
+ if dialect == '0x0311'
145
+ update_preauth_hash(request)
146
+ update_preauth_hash(response)
147
+ end
148
+
149
+ @state = :session_setup
150
+ @dialect = dialect
151
+ response
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,82 @@
1
+ module RubySMB
2
+ class Server
3
+ class ServerClient
4
+ module SessionSetup
5
+ #
6
+ # Setup a new session based on the negotiated dialect. Once session setup is complete, the state will be updated
7
+ # to :authenticated.
8
+ #
9
+ # @param [String] raw_request the session setup request to process
10
+ def handle_session_setup(raw_request)
11
+ response = nil
12
+
13
+ case metadialect.order
14
+ when Dialect::ORDER_SMB1
15
+ request = SMB1::Packet::SessionSetupRequest.read(raw_request)
16
+ response = do_session_setup_smb1(request)
17
+ when Dialect::ORDER_SMB2
18
+ request = SMB2::Packet::SessionSetupRequest.read(raw_request)
19
+ response = do_session_setup_smb2(request)
20
+ end
21
+
22
+ if response.nil?
23
+ disconnect!
24
+ else
25
+ send_packet(response)
26
+ end
27
+
28
+ nil
29
+ end
30
+
31
+ def do_session_setup_smb1(request)
32
+ gss_result = process_gss(request.data_block.security_blob)
33
+ return if gss_result.nil?
34
+
35
+ response = SMB1::Packet::SessionSetupResponse.new
36
+ response.smb_header.pid_low = request.smb_header.pid_low
37
+ response.smb_header.uid = rand(0x10000)
38
+ response.smb_header.mid = request.smb_header.mid
39
+ response.smb_header.nt_status = gss_result.nt_status.value
40
+ response.smb_header.flags.reply = true
41
+ response.smb_header.flags2.unicode = true
42
+ response.smb_header.flags2.extended_security = true
43
+ unless gss_result.buffer.nil?
44
+ response.parameter_block.security_blob_length = gss_result.buffer.length
45
+ response.data_block.security_blob = gss_result.buffer
46
+ end
47
+
48
+ if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
49
+ @state = :authenticated
50
+ @identity = gss_result.identity
51
+ end
52
+
53
+ response
54
+ end
55
+
56
+ def do_session_setup_smb2(request)
57
+ gss_result = process_gss(request.buffer)
58
+ return if gss_result.nil?
59
+
60
+ response = SMB2::Packet::SessionSetupResponse.new
61
+ response.smb2_header.nt_status = gss_result.nt_status.value
62
+ response.smb2_header.credits = 1
63
+ response.smb2_header.message_id = request.smb2_header.message_id
64
+ response.smb2_header.session_id = @session_id = @session_id || SecureRandom.random_bytes(4).unpack1('V')
65
+ response.buffer = gss_result.buffer
66
+
67
+ update_preauth_hash(request) if @dialect == '0x0311'
68
+ if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
69
+ @state = :authenticated
70
+ @identity = gss_result.identity
71
+ @session_key = @gss_authenticator.session_key
72
+ elsif gss_result.nt_status == WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED && @dialect == '0x0311'
73
+ update_preauth_hash(response)
74
+ end
75
+
76
+ response
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,162 @@
1
+ module RubySMB
2
+ class Server
3
+ # This class represents a single connected client to the server. It stores and processes connection specific related
4
+ # information.
5
+ class ServerClient
6
+
7
+ require 'ruby_smb/dialect'
8
+ require 'ruby_smb/signing'
9
+ require 'ruby_smb/server/server_client/negotiation'
10
+ require 'ruby_smb/server/server_client/session_setup'
11
+
12
+ include RubySMB::Signing
13
+ include RubySMB::Server::ServerClient::Negotiation
14
+ include RubySMB::Server::ServerClient::SessionSetup
15
+
16
+ attr_reader :dialect, :identity, :state, :session_key
17
+
18
+ # @param [Server] server the server that accepted this connection
19
+ # @param [Dispatcher::Socket] dispatcher the connection's socket dispatcher
20
+ def initialize(server, dispatcher)
21
+ @server = server
22
+ @dispatcher = dispatcher
23
+ @state = :negotiate
24
+ @dialect = nil
25
+ @session_id = nil
26
+ @session_key = nil
27
+ @gss_authenticator = server.gss_provider.new_authenticator(self)
28
+ @identity = nil
29
+ @tree_connections = {}
30
+ @preauth_integrity_hash_algorithm = nil
31
+ @preauth_integrity_hash_value = nil
32
+ end
33
+
34
+ #
35
+ # The dialects metadata definition.
36
+ #
37
+ # @return [Dialect::Definition]
38
+ def metadialect
39
+ Dialect::ALL[@dialect]
40
+ end
41
+
42
+ #
43
+ # The peername of the connected socket. This is a combination of the IPv4 or IPv6 address and port number.
44
+ #
45
+ # @example Parse the value into an IP address
46
+ # ::Socket::unpack_sockaddr_in(server_client.getpeername)
47
+ #
48
+ # @return [String]
49
+ def getpeername
50
+ @dispatcher.tcp_socket.getpeername
51
+ end
52
+
53
+ #
54
+ # Handle an authenticated request. This is the main handler for all requests after the connection has been
55
+ # authenticated.
56
+ #
57
+ # @param [String] raw_request the request that should be handled
58
+ def handle_authenticated(raw_request)
59
+ response = nil
60
+
61
+ case raw_request[0...4].unpack1('L>')
62
+ when RubySMB::SMB1::SMB_PROTOCOL_ID
63
+ raise NotImplementedError
64
+ when RubySMB::SMB2::SMB2_PROTOCOL_ID
65
+ raise NotImplementedError
66
+ end
67
+
68
+ if response.nil?
69
+ disconnect!
70
+ return
71
+ end
72
+
73
+ send_packet(response)
74
+ end
75
+
76
+ #
77
+ # Process a GSS authentication buffer. If no buffer is specified, the request is assumed to be the first in the
78
+ # negotiation sequence.
79
+ #
80
+ # @param [String, nil] buffer the request GSS request buffer that should be processed
81
+ # @return [Gss::Provider::Result] the result of the processed GSS request
82
+ def process_gss(buffer=nil)
83
+ @gss_authenticator.process(buffer)
84
+ end
85
+
86
+ #
87
+ # Run the processing loop to receive and handle requests. This loop runs until an exception occurs or the
88
+ # dispatcher socket is closed.
89
+ #
90
+ def run
91
+ loop do
92
+ begin
93
+ raw_request = recv_packet
94
+ rescue RubySMB::Error::CommunicationError
95
+ break
96
+ end
97
+
98
+ case @state
99
+ when :negotiate
100
+ handle_negotiate(raw_request)
101
+ when :session_setup
102
+ handle_session_setup(raw_request)
103
+ when :authenticated
104
+ handle_authenticated(raw_request)
105
+ end
106
+
107
+ break if @dispatcher.tcp_socket.closed?
108
+ end
109
+ end
110
+
111
+ #
112
+ # Disconnect the remote client.
113
+ #
114
+ def disconnect!
115
+ @state = nil
116
+ @dispatcher.tcp_socket.close
117
+ end
118
+
119
+ #
120
+ # Receive a single SMB packet from the dispatcher.
121
+ #
122
+ # @return [String] the raw packet
123
+ def recv_packet
124
+ @dispatcher.recv_packet
125
+ end
126
+
127
+ #
128
+ # Send a single SMB packet using the dispatcher. If necessary, the packet will be signed.
129
+ #
130
+ # @param [GenericPacket] packet the packet to send
131
+ def send_packet(packet)
132
+ if @state == :authenticated && @identity != Gss::Provider::IDENTITY_ANONYMOUS && !@session_key.nil?
133
+ case metadialect.family
134
+ when Dialect::FAMILY_SMB2
135
+ packet = smb2_sign(packet)
136
+ when Dialect::FAMILY_SMB3
137
+ packet = smb3_sign(packet)
138
+ end
139
+ end
140
+
141
+ @dispatcher.send_packet(packet)
142
+ end
143
+
144
+ #
145
+ # Update the preauth integrity hash as used by dialect 3.1.1 for various cryptographic operations. The algorithm
146
+ # and hash values must have been initialized prior to calling this.
147
+ #
148
+ # @param [String] data the data with which to update the preauth integrity hash
149
+ def update_preauth_hash(data)
150
+ unless @preauth_integrity_hash_algorithm
151
+ raise RubySMB::Error::EncryptionError.new(
152
+ 'Cannot compute the Preauth Integrity Hash value: Preauth Integrity Hash Algorithm is nil'
153
+ )
154
+ end
155
+ @preauth_integrity_hash_value = OpenSSL::Digest.digest(
156
+ @preauth_integrity_hash_algorithm,
157
+ @preauth_integrity_hash_value + data.to_binary_s
158
+ )
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,54 @@
1
+ require 'socket'
2
+
3
+ module RubySMB
4
+ # This class provides the SMB server core. Settings that are relevant server wide are managed by this object.
5
+ # Currently, the server only supports negotiating and authenticating requests. No other server functionality is
6
+ # available at this time. The negotiating and authentication is supported for SMB versions 1 through 3.1.1.
7
+ class Server
8
+ require 'ruby_smb/server/server_client'
9
+ require 'ruby_smb/gss/provider/ntlm'
10
+
11
+ Connection = Struct.new(:client, :thread)
12
+
13
+ # @param server_sock the socket on which the server should listen
14
+ # @param [Gss::Provider] the authentication provider
15
+ def initialize(server_sock: nil, gss_provider: nil)
16
+ server_sock = ::TCPServer.new(445) if server_sock.nil?
17
+
18
+ @guid = Random.new.bytes(16)
19
+ @socket = server_sock
20
+ @connections = []
21
+ @gss_provider = gss_provider || Gss::Provider::NTLM.new
22
+ # reject the wildcard dialect because it's not a real dialect we can use for this purpose
23
+ @dialects = RubySMB::Dialect::ALL.keys.reject { |dialect| dialect == "0x%04x" % RubySMB::SMB2::SMB2_WILDCARD_REVISION }.reverse
24
+ end
25
+
26
+ # Run the server and accept any connections. For each connection, the block will be executed if specified. When the
27
+ # block returns false, the loop will exit and the server will no long accept new connections.
28
+ def run(&block)
29
+ loop do
30
+ sock = @socket.accept
31
+ server_client = ServerClient.new(self, RubySMB::Dispatcher::Socket.new(sock))
32
+ @connections << Connection.new(server_client, Thread.new { server_client.run })
33
+
34
+ break unless block.nil? || block.call(server_client)
35
+ end
36
+ end
37
+
38
+ # The dialects that this server will negotiate with clients, in ascending order of preference.
39
+ # @!attribute [r] dialects
40
+ # @return [Array<String>]
41
+ attr_accessor :dialects
42
+
43
+ # The GSS Provider instance that this server will use to authenticate
44
+ # incoming client connections.
45
+ # @!attribute [r] gss_provider
46
+ # @return [RubySMB::Gss::Provider::Base]
47
+ attr_reader :gss_provider
48
+
49
+ # The 16 byte GUID that uniquely identifies this server instance.
50
+ # @!attribute [r] guid
51
+ attr_reader :guid
52
+ end
53
+ end
54
+
@@ -0,0 +1,59 @@
1
+ module RubySMB
2
+ # Contains the methods for handling packet signing
3
+ module Signing
4
+ # The NTLM Session Key used for signing
5
+ # @!attribute [rw] session_key
6
+ # @return [String]
7
+ attr_accessor :session_key
8
+
9
+ # Take an SMB1 packet and sign it.
10
+ #
11
+ # @param packet [RubySMB::GenericPacket] the packet to sign
12
+ # @return [RubySMB::GenericPacket] the signed packet
13
+ def smb1_sign(packet)
14
+ # Pack the Sequence counter into a int64le
15
+ packed_sequence_counter = [sequence_counter].pack('Q<')
16
+ packet.smb_header.security_features = packed_sequence_counter
17
+ signature = OpenSSL::Digest::MD5.digest(session_key + packet.to_binary_s)[0, 8]
18
+ packet.smb_header.security_features = signature
19
+ @sequence_counter += 1
20
+
21
+ packet
22
+ end
23
+
24
+ # Take an SMB2 packet and sign it.
25
+ #
26
+ # @param packet [RubySMB::GenericPacket] the packet to sign
27
+ # @return [RubySMB::GenericPacket] the signed packet
28
+ def smb2_sign(packet)
29
+ packet.smb2_header.flags.signed = 1
30
+ packet.smb2_header.signature = "\x00" * 16
31
+ hmac = OpenSSL::HMAC.digest(OpenSSL::Digest.new('SHA256'), session_key, packet.to_binary_s)
32
+ packet.smb2_header.signature = hmac[0, 16]
33
+
34
+ packet
35
+ end
36
+
37
+ # Take an SMB3 packet and sign it.
38
+ #
39
+ # @param packet [RubySMB::GenericPacket] the packet to sign
40
+ # @return [RubySMB::GenericPacket] the signed packet
41
+ def smb3_sign(packet)
42
+ case @dialect
43
+ when '0x0300', '0x0302'
44
+ signing_key = Crypto::KDF.counter_mode(@session_key, "SMB2AESCMAC\x00", "SmbSign\x00")
45
+ when '0x0311'
46
+ signing_key = Crypto::KDF.counter_mode(@session_key, "SMBSigningKey\x00", @preauth_integrity_hash_value)
47
+ else
48
+ raise Error::SigningError.new("Dialect #{@dialect.inspect} is incompatible with SMBv3 signing")
49
+ end
50
+
51
+ packet.smb2_header.flags.signed = 1
52
+ packet.smb2_header.signature = "\x00" * 16
53
+ hmac = OpenSSL::CMAC.digest('AES', signing_key, packet.to_binary_s)
54
+ packet.smb2_header.signature = hmac[0, 16]
55
+
56
+ packet
57
+ end
58
+ end
59
+ end
@@ -86,8 +86,7 @@ module RubySMB
86
86
  raise RubySMB::Error::InvalidPacket.new(
87
87
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
88
88
  expected_cmd: RubySMB::SMB1::Packet::CloseResponse::COMMAND,
89
- received_proto: response.smb_header.protocol,
90
- received_cmd: response.smb_header.command
89
+ packet: response
91
90
  )
92
91
  end
93
92
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -106,11 +105,7 @@ module RubySMB
106
105
  # @raise [RubySMB::Error::InvalidPacket] if the response packet is not valid
107
106
  # @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
108
107
  def read(bytes: @size, offset: 0)
109
- atomic_read_size = if bytes > @tree.client.max_buffer_size
110
- @tree.client.max_buffer_size
111
- else
112
- bytes
113
- end
108
+ atomic_read_size = [bytes, @tree.client.max_buffer_size].min
114
109
  remaining_bytes = bytes
115
110
  data = ''
116
111
 
@@ -122,8 +117,7 @@ module RubySMB
122
117
  raise RubySMB::Error::InvalidPacket.new(
123
118
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
124
119
  expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
125
- received_proto: response.smb_header.protocol,
126
- received_cmd: response.smb_header.command
120
+ packet: response
127
121
  )
128
122
  end
129
123
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -171,8 +165,7 @@ module RubySMB
171
165
  raise RubySMB::Error::InvalidPacket.new(
172
166
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
173
167
  expected_cmd: RubySMB::SMB1::Packet::ReadAndxResponse::COMMAND,
174
- received_proto: response.smb_header.protocol,
175
- received_cmd: response.smb_header.command
168
+ packet: response
176
169
  )
177
170
  end
178
171
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -193,8 +186,7 @@ module RubySMB
193
186
  raise RubySMB::Error::InvalidPacket.new(
194
187
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
195
188
  expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
196
- received_proto: response.smb_header.protocol,
197
- received_cmd: response.smb_header.command
189
+ packet: response
198
190
  )
199
191
  end
200
192
  response.status_code
@@ -227,11 +219,7 @@ module RubySMB
227
219
  total_bytes_written = 0
228
220
 
229
221
  loop do
230
- atomic_write_size = if bytes > @tree.client.max_buffer_size
231
- @tree.client.max_buffer_size
232
- else
233
- bytes
234
- end
222
+ atomic_write_size = [bytes, @tree.client.max_buffer_size].min
235
223
  write_request = write_packet(data: buffer.slice!(0, atomic_write_size), offset: offset)
236
224
  raw_response = @tree.client.send_recv(write_request)
237
225
  response = RubySMB::SMB1::Packet::WriteAndxResponse.read(raw_response)
@@ -239,8 +227,7 @@ module RubySMB
239
227
  raise RubySMB::Error::InvalidPacket.new(
240
228
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
241
229
  expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
242
- received_proto: response.smb_header.protocol,
243
- received_cmd: response.smb_header.command
230
+ packet: response
244
231
  )
245
232
  end
246
233
  unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
@@ -279,8 +266,7 @@ module RubySMB
279
266
  raise RubySMB::Error::InvalidPacket.new(
280
267
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
281
268
  expected_cmd: RubySMB::SMB1::Packet::WriteAndxResponse::COMMAND,
282
- received_proto: response.smb_header.protocol,
283
- received_cmd: response.smb_header.command
269
+ packet: response
284
270
  )
285
271
  end
286
272
  response.parameter_block.count_low
@@ -298,8 +284,7 @@ module RubySMB
298
284
  raise RubySMB::Error::InvalidPacket.new(
299
285
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
300
286
  expected_cmd: RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse::COMMAND,
301
- received_proto: response.smb_header.protocol,
302
- received_cmd: response.smb_header.command
287
+ packet: response
303
288
  )
304
289
  end
305
290
  response.status_code
@@ -316,7 +301,7 @@ module RubySMB
316
301
  passthrough_info_level = RubySMB::Fscc::FileInformation::FILE_RENAME_INFORMATION +
317
302
  RubySMB::Fscc::FileInformation::SMB_INFO_PASSTHROUGH
318
303
  rename_request.data_block.trans2_parameters.information_level = passthrough_info_level
319
- rename_request.data_block.trans2_data.info_level_struct.file_name = new_file_name.encode('utf-16le')
304
+ rename_request.data_block.trans2_data.info_level_struct.file_name = new_file_name
320
305
  set_trans2_params(rename_request)
321
306
  end
322
307
 
@@ -8,17 +8,17 @@ module RubySMB
8
8
 
9
9
  # An SMB_Parameters Block as defined by the {NegotiateResponse}.
10
10
  class ParameterBlock < RubySMB::SMB1::ParameterBlock
11
- uint16 :dialect_index, label: 'Dialect Index'
12
- security_mode :security_mode
13
- uint16 :max_mpx_count, label: 'Max Multiplex Count'
14
- uint16 :max_number_vcs, label: 'Max Virtual Circuits'
15
- uint32 :max_buffer_size, label: 'Max Buffer Size'
16
- uint32 :max_raw_size, label: 'Max Raw Size'
17
- uint32 :session_key, label: 'Session Key'
18
- capabilities :capabilities
19
- file_time :system_time, label: 'Server System Time'
20
- int16 :server_time_zone, label: 'Server TimeZone'
21
- uint8 :challenge_length, label: 'Challenge Length', initial_value: 0x08
11
+ uint16 :dialect_index, label: 'Dialect Index'
12
+ security_mode :security_mode, onlyif: -> { dialect_index != 0xffff }
13
+ uint16 :max_mpx_count, label: 'Max Multiplex Count', onlyif: -> { dialect_index != 0xffff }
14
+ uint16 :max_number_vcs, label: 'Max Virtual Circuits', onlyif: -> { dialect_index != 0xffff }
15
+ uint32 :max_buffer_size, label: 'Max Buffer Size', onlyif: -> { dialect_index != 0xffff }
16
+ uint32 :max_raw_size, label: 'Max Raw Size', onlyif: -> { dialect_index != 0xffff }
17
+ uint32 :session_key, label: 'Session Key', onlyif: -> { dialect_index != 0xffff }
18
+ capabilities :capabilities, onlyif: -> { dialect_index != 0xffff }
19
+ file_time :system_time, label: 'Server System Time', onlyif: -> { dialect_index != 0xffff }
20
+ int16 :server_time_zone, label: 'Server TimeZone', onlyif: -> { dialect_index != 0xffff }
21
+ uint8 :challenge_length, label: 'Challenge Length', initial_value: 0x08, onlyif: -> { dialect_index != 0xffff }
22
22
  end
23
23
 
24
24
  # An SMB_Data Block as defined by the {NegotiateResponse}
@@ -8,7 +8,7 @@ module RubySMB
8
8
 
9
9
  # An SMB_Parameters Block as defined by the {NegotiateResponseExtended}.
10
10
  class ParameterBlock < RubySMB::SMB1::ParameterBlock
11
- uint16 :dialect_index, label: 'Dialect Index'
11
+ uint16 :dialect_index, label: 'Dialect Index'
12
12
  security_mode :security_mode
13
13
  uint16 :max_mpx_count, label: 'Max Multiplex Count'
14
14
  uint16 :max_number_vcs, label: 'Max Virtual Circuits'
@@ -47,7 +47,7 @@ module RubySMB
47
47
 
48
48
  # Takes an NTLM Type 3 Message and creates the GSS Security Blob
49
49
  # for it and sets it in the {RubySMB::SMB1::Packet::SessionSetupRequest::DataBlock#security_blob}
50
- # field. It also automaticaly sets the length in
50
+ # field. It also automatically sets the length in
51
51
  # {RubySMB::SMB1::Packet::SessionSetupRequest::ParameterBlock#security_blob_length}
52
52
  #
53
53
  # @param type3_message [String] the serialized Type 3 NTLM message
@@ -40,7 +40,6 @@ module RubySMB
40
40
 
41
41
  # The {RubySMB::SMB1::DataBlock} specific to this packet type.
42
42
  class DataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
43
- uint8 :name, label: 'Name', initial_value: 0x00
44
43
  string :pad1, length: -> { pad1_length }
45
44
  trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
46
45
  string :pad2, length: -> { pad2_length }