ruby_smb 2.0.12 → 3.0.2

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 (279) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +1 -1
  4. data/examples/auth_capture.rb +28 -0
  5. data/examples/dump_secrets_from_sid.rb +207 -0
  6. data/examples/enum_domain_users.rb +75 -0
  7. data/examples/file_server.rb +76 -0
  8. data/examples/get_computer_info.rb +42 -0
  9. data/examples/query_service_status.rb +42 -4
  10. data/lib/ruby_smb/client.rb +3 -14
  11. data/lib/ruby_smb/create_actions.rb +21 -0
  12. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  13. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  14. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  15. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  16. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  17. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  18. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  19. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  20. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  21. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  22. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  23. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  24. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  25. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  26. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  27. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request.rb +20 -0
  28. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response.rb +20 -0
  29. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request.rb +21 -0
  30. data/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response.rb +21 -0
  31. data/lib/ruby_smb/dcerpc/encrypting_file_system.rb +44 -0
  32. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  33. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  34. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  35. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  36. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  37. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  38. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  39. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  40. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  41. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  42. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  43. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  44. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  45. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  46. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  47. data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request.rb +22 -0
  48. data/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response.rb +20 -0
  49. data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request.rb +24 -0
  50. data/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response.rb +23 -0
  51. data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request.rb +24 -0
  52. data/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response.rb +22 -0
  53. data/lib/ruby_smb/dcerpc/print_system.rb +69 -0
  54. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  55. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  56. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  57. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  58. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  59. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  60. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  66. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  67. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  68. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  69. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  70. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  79. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  80. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  81. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  82. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  83. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  84. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  85. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  86. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  87. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  88. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  89. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  90. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  91. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  92. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  93. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  94. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  95. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  96. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  97. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  98. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  99. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  100. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  101. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  102. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  103. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  104. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  105. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  106. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  107. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  108. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  109. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  110. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  111. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  112. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  113. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  114. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  115. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  116. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  117. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  118. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  119. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  120. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  121. data/lib/ruby_smb/dcerpc.rb +43 -13
  122. data/lib/ruby_smb/field/file_time.rb +1 -1
  123. data/lib/ruby_smb/field/nt_status.rb +20 -1
  124. data/lib/ruby_smb/field/string16.rb +5 -1
  125. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
  126. data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
  127. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
  128. data/lib/ruby_smb/fscc/file_information.rb +29 -0
  129. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
  130. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
  131. data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
  132. data/lib/ruby_smb/fscc.rb +1 -0
  133. data/lib/ruby_smb/generic_packet.rb +6 -0
  134. data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
  135. data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
  136. data/lib/ruby_smb/ntlm.rb +18 -2
  137. data/lib/ruby_smb/server/server_client/negotiation.rb +0 -2
  138. data/lib/ruby_smb/server/server_client/session_setup.rb +43 -32
  139. data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
  140. data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
  141. data/lib/ruby_smb/server/server_client.rb +214 -24
  142. data/lib/ruby_smb/server/session.rb +71 -0
  143. data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
  144. data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
  145. data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
  146. data/lib/ruby_smb/server/share/provider.rb +38 -0
  147. data/lib/ruby_smb/server/share.rb +11 -0
  148. data/lib/ruby_smb/server.rb +35 -3
  149. data/lib/ruby_smb/signing.rb +37 -11
  150. data/lib/ruby_smb/smb1/commands.rb +4 -0
  151. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  152. data/lib/ruby_smb/smb1.rb +0 -1
  153. data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
  154. data/lib/ruby_smb/smb2/commands.rb +4 -0
  155. data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
  156. data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
  157. data/lib/ruby_smb/smb2/create_context.rb +74 -22
  158. data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
  159. data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
  160. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
  161. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
  162. data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
  163. data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
  164. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
  165. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
  166. data/lib/ruby_smb/smb2/packet.rb +2 -0
  167. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  168. data/lib/ruby_smb/smb2.rb +11 -0
  169. data/lib/ruby_smb/smb_error.rb +110 -0
  170. data/lib/ruby_smb/version.rb +1 -1
  171. data/lib/ruby_smb.rb +2 -0
  172. data/ruby_smb.gemspec +1 -1
  173. data/spec/lib/ruby_smb/client_spec.rb +1 -2
  174. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  175. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  176. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  177. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  178. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_request_spec.rb +30 -0
  179. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_encrypt_file_srv_response_spec.rb +30 -0
  180. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_request_spec.rb +38 -0
  181. data/spec/lib/ruby_smb/dcerpc/encrypting_file_system/efs_rpc_open_file_raw_response_spec.rb +38 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  187. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  188. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  189. data/spec/lib/ruby_smb/dcerpc/print_system/driver_container_spec.rb +41 -0
  190. data/spec/lib/ruby_smb/dcerpc/print_system/driver_info2_spec.rb +64 -0
  191. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_request_spec.rb +59 -0
  192. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_add_printer_driver_ex_response_spec.rb +30 -0
  193. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_request_spec.rb +62 -0
  194. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_enum_printer_drivers_response_spec.rb +54 -0
  195. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_request_spec.rb +62 -0
  196. data/spec/lib/ruby_smb/dcerpc/print_system/rpc_get_printer_driver_directory_response_spec.rb +46 -0
  197. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  198. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  199. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  200. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  201. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  210. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  211. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  212. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  213. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  214. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  215. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  216. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  217. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  218. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  230. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  231. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  232. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  233. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  234. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  235. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  236. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  237. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  238. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  239. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  240. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  241. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  242. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  243. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  244. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  245. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  246. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  247. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  248. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  249. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  250. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  251. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  252. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  253. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  254. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  255. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  256. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  257. data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
  258. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
  261. data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
  262. data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
  263. data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
  264. data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
  265. data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
  266. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  267. data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
  268. data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
  269. data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
  270. data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
  271. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
  272. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  273. data/spec/support/bin_helper.rb +9 -0
  274. data.tar.gz.sig +0 -0
  275. metadata +165 -10
  276. metadata.gz.sig +0 -0
  277. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  278. data/lib/ruby_smb/smb1/create_actions.rb +0 -20
  279. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
@@ -3,7 +3,7 @@ require 'date'
3
3
  module RubySMB
4
4
  module Field
5
5
  # Represents a Windows FILETIME structure as defined in
6
- # [FILETIME structure](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx)
6
+ # [2.3.3 FILETIME](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/2c57429b-fdd4-488f-b5fc-9e4cf020fcdf).aspx)
7
7
  class FileTime < BinData::Primitive
8
8
  # Difference between the Windows and Unix epochs, in 100ns intervals
9
9
  EPOCH_DIFF_100NS = 116_444_736_000_000_000
@@ -4,7 +4,26 @@ module RubySMB
4
4
  module Field
5
5
  # Represents an NTStatus code as defined in
6
6
  # [2.3.1 NTSTATUS values](https://msdn.microsoft.com/en-us/library/cc704588.aspx)
7
- class NtStatus < BinData::Uint32le
7
+ class NtStatus < BinData::Primitive
8
+ endian :little
9
+ uint32 :val
10
+
11
+ def get
12
+ val.to_i
13
+ end
14
+
15
+ def set(value)
16
+ case value
17
+ when WindowsError::ErrorCode
18
+ set(value.value)
19
+ when Integer
20
+ self.val = value
21
+ else
22
+ self.val = value.to_i
23
+ end
24
+ val
25
+ end
26
+
8
27
  # Returns a meaningful error code parsed from the numeric value
9
28
  #
10
29
  # @return [WindowsError::ErrorCode] the ErrorCode object for this code
@@ -3,12 +3,16 @@ module RubySMB
3
3
  # Represents a String in UTF-16LE
4
4
  class String16 < BinData::String
5
5
  def assign(val)
6
- super(val.encode('utf-16le'))
6
+ super(val.to_s.encode('utf-16le')).force_encoding('utf-16le')
7
7
  end
8
8
 
9
9
  def snapshot
10
10
  super.force_encoding('utf-16le')
11
11
  end
12
+
13
+ def read_and_return_value(io)
14
+ super.force_encoding('utf-16le')
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -0,0 +1,14 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileEaInformation Class as defined in
5
+ # [2.4.12 FileEaInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/db6cf109-ead8-441a-b29e-cb2032778b0f)
6
+ class FileEaInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_EA_INFORMATION
8
+
9
+ endian :little
10
+ uint32 :ea_size, label: 'Extended Attributes Size'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileNetworkOpenInformation Class as defined in
5
+ # [2.4.29 FileNetworkOpenInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/26d261db-58d1-4513-a548-074448cbb146)
6
+ class FileNetworkOpenInformation < BinData::Record
7
+ CLASS_LEVEL = FileInformation::FILE_NETWORK_OPEN_INFORMATION
8
+
9
+ endian :little
10
+
11
+ file_time :create_time, label: 'Create Time'
12
+ file_time :last_access, label: 'Last Accessed Time'
13
+ file_time :last_write, label: 'Last Write Time'
14
+ file_time :last_change, label: 'Last Modified Time'
15
+ int64 :allocation_size, label: 'Allocated Size'
16
+ int64 :end_of_file, label: 'End of File'
17
+ file_attributes :file_attributes, label: 'File Attributes'
18
+ uint32 :reserved, label: 'Reserved Space'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileInformation
4
+ # The FileStreamInformation
5
+ # [2.4.43 FileStreamInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/f8762be6-3ab9-411e-a7d6-5cc68f70c78d)
6
+ class FileStreamInformation < BinData::Record
7
+ endian :little
8
+ uint32 :next_entry_offset, label: 'Next Entry Offset'
9
+ uint32 :stream_name_length, label: 'Stream Name Length', initial_value: -> { stream_name.do_num_bytes }
10
+ int64 :stream_size, label: 'Stream Size'
11
+ int64 :stream_allocation_size, label: 'Stream Allocation Size'
12
+ string16 :stream_name, label: 'Stream Name', read_length: -> { stream_name_length }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -17,6 +17,10 @@ module RubySMB
17
17
  # contents of a directory.
18
18
  FILE_BOTH_DIRECTORY_INFORMATION = 0x03
19
19
 
20
+ # Information class used to query for the size of the extended attributes
21
+ # (EA) for a file.
22
+ FILE_EA_INFORMATION = 0x07
23
+
20
24
  # Information class used to rename a file.
21
25
  FILE_RENAME_INFORMATION = 0x0A
22
26
 
@@ -27,6 +31,14 @@ module RubySMB
27
31
  # Information class used to mark a file for deletion.
28
32
  FILE_DISPOSITION_INFORMATION = 0x0D
29
33
 
34
+ # Information class used to enumerate the data streams of a file or a
35
+ # directory.
36
+ FILE_STREAM_INFORMATION = 0x16
37
+
38
+ # This information class is used to query for information that is commonly
39
+ # needed when a file is opened across a network.
40
+ FILE_NETWORK_OPEN_INFORMATION = 0x22
41
+
30
42
  # Information class used in directory enumeration to return detailed
31
43
  # information (with extended attributes size, short names and file ID)
32
44
  # about the contents of a directory.
@@ -38,6 +50,13 @@ module RubySMB
38
50
  FILE_ID_FULL_DIRECTORY_INFORMATION = 0x26
39
51
 
40
52
 
53
+ # This information class is used to query the normalized name of a file. A
54
+ # normalized name is an absolute pathname where each short name component
55
+ # has been replaced with the corresponding long name component, and each
56
+ # name component uses the exact letter casing stored on disk.
57
+ FILE_NORMALIZED_NAME_INFORMATION = 0x30
58
+
59
+
41
60
  # These Information Classes can be used by SMB1 using the pass-through
42
61
  # Information Levels when available on the server (CAP_INFOLEVEL_PASSTHRU
43
62
  # capability flag in an SMB_COM_NEGOTIATE server response). The constant
@@ -46,6 +65,13 @@ module RubySMB
46
65
  # [2.2.2.3.5 Pass-through Information Level Codes](https://msdn.microsoft.com/en-us/library/ff470158.aspx)
47
66
  SMB_INFO_PASSTHROUGH = 0x03e8
48
67
 
68
+ # The FILE_NAME_INFORMATION type as defined in
69
+ # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/20406fb1-605f-4629-ba9a-c67ee25f23d2
70
+ class FileNameInformation < BinData::Record
71
+ endian :little
72
+ uint32 :file_name_length, label: 'File Name Length', initial_value: -> { file_name.do_num_bytes }
73
+ string16 :file_name, label: 'File Name', read_length: -> { file_name_length }
74
+ end
49
75
 
50
76
  require 'ruby_smb/fscc/file_information/file_directory_information'
51
77
  require 'ruby_smb/fscc/file_information/file_full_directory_information'
@@ -55,6 +81,9 @@ module RubySMB
55
81
  require 'ruby_smb/fscc/file_information/file_id_both_directory_information'
56
82
  require 'ruby_smb/fscc/file_information/file_names_information'
57
83
  require 'ruby_smb/fscc/file_information/file_rename_information'
84
+ require 'ruby_smb/fscc/file_information/file_network_open_information'
85
+ require 'ruby_smb/fscc/file_information/file_ea_information'
86
+ require 'ruby_smb/fscc/file_information/file_stream_information'
58
87
  end
59
88
  end
60
89
  end
@@ -0,0 +1,46 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileSystemInformation
4
+ # The FileFsAttributeInformation
5
+ # [2.5.1 FileFsAttributeInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ebc7e6e5-4650-4e54-b17c-cf60f6fbeeaa)
6
+ class FileFsAttributeInformation < BinData::Record
7
+ CLASS_LEVEL = FileSystemInformation::FILE_FS_ATTRIBUTE_INFORMATION
8
+
9
+ endian :little
10
+ struct :file_system_attributes, label: 'File System Attributes' do
11
+ bit1 :file_supports_reparse_points, label: 'FS Supports Reparse Points'
12
+ bit1 :file_supports_sparse_files, label: 'FS Supports Sparse Files'
13
+ bit1 :file_volume_quotas, label: 'FS Supports Quotas'
14
+ bit1 :file_file_compression, label: 'FS Supports File Compression'
15
+ bit1 :file_persistent_acls, label: 'FS Supports Persistent ACLs'
16
+ bit1 :file_unicode_on_disk, label: 'FS Supports Unicode Names'
17
+ bit1 :file_case_preserved_names, label: 'FS Preserves Name Casing'
18
+ bit1 :file_case_sensitive_search, label: 'FS Supports Case-Sensitive Searching'
19
+ # byte boundary
20
+ bit1 :file_volume_is_compressed, label: 'FS Is Compressed'
21
+ bit6 :reserved0
22
+ bit1 :file_supports_remote_storage, label: 'FS Supports Remote Storage'
23
+ # byte boundary
24
+ bit1 :file_supports_extended_attributes, label: 'FS Supports Persistent Extended Attributes'
25
+ bit1 :file_supports_hard_links, label: 'FS Supports Hard Links'
26
+ bit1 :file_supports_transactions, label: 'FS Supports Transactions'
27
+ bit1 :file_sequential_write_once, label: 'FS Is Write Once'
28
+ bit1 :file_read_only_volume, label: 'FS Is Read-Only'
29
+ bit1 :file_named_streams, label: 'FS Supports Named Streams'
30
+ bit1 :file_supports_encryption, label: 'FS Supports Encryption'
31
+ bit1 :file_supports_object_ids, label: 'FS Supports Object IDs'
32
+ # byte boundary
33
+ bit3 :reserved1
34
+ bit1 :file_supports_sparse_vdl, label: 'FS Supports Sparse VDL'
35
+ bit1 :file_supports_block_refcounting, label: 'FS Supports Block Reference Counting'
36
+ bit1 :file_supports_integrity_streams, label: 'FS Supports Integrity Streams'
37
+ bit1 :file_supports_usn_journal, label: 'FS Supports USN Change Journal'
38
+ bit1 :file_supports_open_by_file_id, label: 'FS Supports Open By File ID'
39
+ end
40
+ int32 :maximum_component_name_length, label: 'Maximum Component Name Length'
41
+ uint32 :file_system_name_length, label: 'File System Name Length', initial_value: -> { file_system_name.do_num_bytes }
42
+ string16 :file_system_name, label: 'File System Name', read_length: -> { file_system_name_length }
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ module RubySMB
2
+ module Fscc
3
+ module FileSystemInformation
4
+ # The FileFsVolumeInformation
5
+ # [2.5.9 FileFsVolumeInformation](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/bf691378-c34e-4a13-976e-404ea1a87738)
6
+ class FileFsVolumeInformation < BinData::Record
7
+ CLASS_LEVEL = FileSystemInformation::FILE_FS_VOLUME_INFORMATION
8
+
9
+ endian :little
10
+ file_time :volume_creation_time, label: 'Volume Creation Time'
11
+ uint32 :volume_serial_number, label: 'Volume Serial Number'
12
+ uint32 :volume_label_length, label: 'Volume Label Length', initial_value: -> { volume_label.do_num_bytes }
13
+ uint8 :supports_objects, label: 'Supports Objects'
14
+ uint8 :reserved, label: 'Reserved'
15
+ string16 :volume_label, label: 'Volume Label', read_length: -> { volume_label_length }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module RubySMB
2
+ module Fscc
3
+ # Namespace and constant values for File System Information Classes, as defined in
4
+ # [2.5 File System Information Classes](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ee12042a-9352-46e3-9f67-c094b75fe6c3)
5
+ module FileSystemInformation
6
+ FILE_FS_VOLUME_INFORMATION = 1
7
+ FILE_FS_LABEL_INFORMATION = 2
8
+ FILE_FS_SIZE_INFORMATION = 3
9
+ FILE_FS_DEVICE_INFORMATION = 4
10
+ FILE_FS_ATTRIBUTE_INFORMATION = 5
11
+ FILE_FS_CONTROL_INFORMATION = 6
12
+ FILE_FS_FULL_SIZE_INFORMATION = 7
13
+ FILE_FS_OBJECT_ID_INFORMATION = 8
14
+ FILE_FS_DRIVER_PATH_INFORMATION = 9
15
+ FILE_FS_VOLUME_FLAGS_INFORMATION = 10
16
+ FILE_FS_SECTOR_SIZE_INFORMATION = 11
17
+
18
+ require 'ruby_smb/fscc/file_system_information/file_fs_attribute_information'
19
+ require 'ruby_smb/fscc/file_system_information/file_fs_volume_information'
20
+ end
21
+ end
22
+ end
data/lib/ruby_smb/fscc.rb CHANGED
@@ -7,6 +7,7 @@ module RubySMB
7
7
  require 'ruby_smb/fscc/file_full_ea_info'
8
8
  require 'ruby_smb/fscc/ea_info_array'
9
9
  require 'ruby_smb/fscc/file_information'
10
+ require 'ruby_smb/fscc/file_system_information'
10
11
  require 'ruby_smb/fscc/control_codes'
11
12
  end
12
13
  end
@@ -43,6 +43,8 @@ module RubySMB
43
43
  begin
44
44
  super(val)
45
45
  rescue IOError => e
46
+ # $stderr.puts "#{e.class}: #{e.message}"
47
+ # $stderr.puts e.backtrace.join("\n")
46
48
  case self.to_s
47
49
  when /EmptyPacket|ErrorPacket/
48
50
  raise RubySMB::Error::InvalidPacket, 'Not a valid SMB packet'
@@ -68,6 +70,10 @@ module RubySMB
68
70
  end
69
71
  end
70
72
 
73
+ def self.from_hex(val)
74
+ self.read(val.scan(/../).map { |x| x.hex.chr }.join)
75
+ end
76
+
71
77
  def status_code
72
78
  value = -1
73
79
  smb_version = packet_smb_version
@@ -17,6 +17,10 @@ module RubySMB
17
17
  reset!
18
18
  end
19
19
 
20
+ def logger
21
+ @server_client.logger
22
+ end
23
+
20
24
  #
21
25
  # Process a GSS authentication buffer. If no buffer is specified, the request is assumed to be the first in
22
26
  # the negotiation sequence.
@@ -50,7 +50,8 @@ module RubySMB
50
50
 
51
51
  begin
52
52
  gss_api = OpenSSL::ASN1.decode(request_buffer)
53
- rescue OpenSSL::ASN1::ASN1Error
53
+ rescue OpenSSL::ASN1::ASN1Error => e
54
+ logger.error("Failed to parse the ASN1-encoded authentication request (#{e.message})")
54
55
  return
55
56
  end
56
57
 
@@ -114,11 +115,16 @@ module RubySMB
114
115
  return WindowsError::NTStatus::STATUS_LOGON_FAILURE
115
116
  end
116
117
 
118
+ dbg_string = "#{type3_msg.domain.encode(''.encoding)}\\#{type3_msg.user.encode(''.encoding)}"
119
+ logger.debug("NTLM authentication request received for #{dbg_string}")
117
120
  account = @provider.get_account(
118
121
  type3_msg.user,
119
122
  domain: type3_msg.domain
120
123
  )
121
- return WindowsError::NTStatus::STATUS_LOGON_FAILURE if account.nil?
124
+ if account.nil?
125
+ logger.info("NTLM authentication request failed for #{dbg_string} (no account)")
126
+ return WindowsError::NTStatus::STATUS_LOGON_FAILURE
127
+ end
122
128
 
123
129
  matches = false
124
130
  case type3_msg.ntlm_version
@@ -159,8 +165,12 @@ module RubySMB
159
165
  raise NotImplementedError, "authentication via ntlm version #{type3_msg.ntlm_version} is not supported"
160
166
  end
161
167
 
162
- return WindowsError::NTStatus::STATUS_LOGON_FAILURE unless matches
168
+ unless matches
169
+ logger.info("NTLM authentication request failed for #{dbg_string} (bad password)")
170
+ return WindowsError::NTStatus::STATUS_LOGON_FAILURE
171
+ end
163
172
 
173
+ logger.info("NTLM authentication request succeeded for #{dbg_string}")
164
174
  WindowsError::NTStatus::STATUS_SUCCESS
165
175
  end
166
176
 
data/lib/ruby_smb/ntlm.rb CHANGED
@@ -28,13 +28,29 @@ module RubySMB
28
28
  :KEY56 => 1 << 31
29
29
  }.freeze
30
30
 
31
+ DEFAULT_CLIENT_FLAGS =
32
+ NEGOTIATE_FLAGS[:UNICODE] |
33
+ NEGOTIATE_FLAGS[:SIGN] |
34
+ NEGOTIATE_FLAGS[:SEAL] |
35
+ NEGOTIATE_FLAGS[:REQUEST_TARGET] |
36
+ NEGOTIATE_FLAGS[:NTLM] |
37
+ NEGOTIATE_FLAGS[:ALWAYS_SIGN] |
38
+ NEGOTIATE_FLAGS[:EXTENDED_SECURITY] |
39
+ NEGOTIATE_FLAGS[:KEY128] |
40
+ NEGOTIATE_FLAGS[:KEY_EXCHANGE] |
41
+ NEGOTIATE_FLAGS[:KEY56] |
42
+ NEGOTIATE_FLAGS[:TARGET_INFO] |
43
+ NEGOTIATE_FLAGS[:VERSION_INFO]
44
+
45
+ # [[MS-NLMP] 2.2.2.10 VERSION](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b1a6ceb2-f8ad-462b-b5af-f18527c48175)
31
46
  class OSVersion < BinData::Record
32
- endian :big
47
+ endian :little
33
48
 
34
49
  uint8 :major
35
50
  uint8 :minor
36
51
  uint16 :build
37
- uint32 :ntlm_revision, initial_value: 15
52
+ uint24 :reserved
53
+ uint8 :ntlm_revision, initial_value: 15
38
54
 
39
55
  def to_s
40
56
  "Version #{major}.#{minor} (Build #{build}); NTLM Current Revision #{ntlm_revision}"
@@ -73,7 +73,6 @@ module RubySMB
73
73
  response.data_block.server_guid = @server.guid
74
74
  response.data_block.security_blob = process_gss.buffer
75
75
 
76
- @state = :session_setup
77
76
  @dialect = dialect
78
77
  response
79
78
  end
@@ -146,7 +145,6 @@ module RubySMB
146
145
  update_preauth_hash(response)
147
146
  end
148
147
 
149
- @state = :session_setup
150
148
  @dialect = dialect
151
149
  response
152
150
  end
@@ -2,39 +2,26 @@ module RubySMB
2
2
  class Server
3
3
  class ServerClient
4
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!
5
+ def do_session_setup_smb1(request, session)
6
+ session_id = request.smb_header.uid
7
+ if session_id == 0
8
+ session_id = rand(1..0x10000)
9
+ session = @session_table[session_id] = Server::Session.new(session_id)
24
10
  else
25
- send_packet(response)
11
+ session = @session_table[session_id]
12
+ if session.nil?
13
+ response = SMB1::Packet::EmptyPacket.new
14
+ response.smb_header.nt_status = SMBError::STATUS_SMB_BAD_UID
15
+ return response
16
+ end
26
17
  end
27
18
 
28
- nil
29
- end
30
-
31
- def do_session_setup_smb1(request)
32
19
  gss_result = process_gss(request.data_block.security_blob)
33
20
  return if gss_result.nil?
34
21
 
35
22
  response = SMB1::Packet::SessionSetupResponse.new
36
23
  response.smb_header.pid_low = request.smb_header.pid_low
37
- response.smb_header.uid = rand(0x10000)
24
+ response.smb_header.uid = session_id
38
25
  response.smb_header.mid = request.smb_header.mid
39
26
  response.smb_header.nt_status = gss_result.nt_status.value
40
27
  response.smb_header.flags.reply = true
@@ -46,14 +33,28 @@ module RubySMB
46
33
  end
47
34
 
48
35
  if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
49
- @state = :authenticated
50
- @identity = gss_result.identity
36
+ session.state = :valid
37
+ session.user_id = gss_result.identity
38
+ session.key = @gss_authenticator.session_key
51
39
  end
52
40
 
53
41
  response
54
42
  end
55
43
 
56
- def do_session_setup_smb2(request)
44
+ def do_session_setup_smb2(request, session)
45
+ session_id = request.smb2_header.session_id
46
+ if session_id == 0
47
+ session_id = rand(1..0xfffffffe)
48
+ session = @session_table[session_id] = Session.new(session_id)
49
+ else
50
+ session = @session_table[session_id]
51
+ if session.nil?
52
+ response = SMB2::Packet::ErrorPacket.new
53
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_USER_SESSION_DELETED
54
+ return response
55
+ end
56
+ end
57
+
57
58
  gss_result = process_gss(request.buffer)
58
59
  return if gss_result.nil?
59
60
 
@@ -61,20 +62,30 @@ module RubySMB
61
62
  response.smb2_header.nt_status = gss_result.nt_status.value
62
63
  response.smb2_header.credits = 1
63
64
  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.smb2_header.session_id = session_id
65
66
  response.buffer = gss_result.buffer
66
67
 
67
68
  update_preauth_hash(request) if @dialect == '0x0311'
68
69
  if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
69
- @state = :authenticated
70
- @identity = gss_result.identity
71
- @session_key = @gss_authenticator.session_key
70
+ response.smb2_header.credits = 32
71
+ session.state = :valid
72
+ session.user_id = gss_result.identity
73
+ session.key = @gss_authenticator.session_key
74
+ session.signing_required = request.security_mode.signing_required == 1
72
75
  elsif gss_result.nt_status == WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED && @dialect == '0x0311'
73
76
  update_preauth_hash(response)
74
77
  end
75
78
 
76
79
  response
77
80
  end
81
+
82
+ def do_logoff_smb2(request, session)
83
+ session = @session_table.delete(session.id)
84
+ session.logoff!
85
+
86
+ response = SMB2::Packet::LogoffResponse.new
87
+ response
88
+ end
78
89
  end
79
90
  end
80
91
  end
@@ -0,0 +1,28 @@
1
+ module RubySMB
2
+ class Server
3
+ class ServerClient
4
+ module ShareIO
5
+ def proxy_share_io_smb2(request, session)
6
+ # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/9a639360-87be-4d49-a1dd-4c6be0c020bd
7
+ share_processor = session.tree_connect_table[request.smb2_header.tree_id]
8
+ if share_processor.nil?
9
+ response = SMB2::Packet::ErrorPacket.new
10
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NETWORK_NAME_DELETED
11
+ return response
12
+ end
13
+
14
+ logger.debug("Received #{SMB2::Commands.name(request.smb2_header.command)} request for share: #{share_processor.provider.name}")
15
+ share_processor.send(__callee__, request)
16
+ end
17
+
18
+ alias :do_close_smb2 :proxy_share_io_smb2
19
+ alias :do_create_smb2 :proxy_share_io_smb2
20
+ alias :do_ioctl_smb2 :proxy_share_io_smb2
21
+ alias :do_query_directory_smb2 :proxy_share_io_smb2
22
+ alias :do_query_info_smb2 :proxy_share_io_smb2
23
+ alias :do_read_smb2 :proxy_share_io_smb2
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,60 @@
1
+ module RubySMB
2
+ class Server
3
+ class ServerClient
4
+ MAX_TREE_CONNECTIONS = 1000
5
+ module TreeConnect
6
+ def do_tree_connect_smb2(request, session)
7
+ response = RubySMB::SMB2::Packet::TreeConnectResponse.new
8
+ response.smb2_header.credits = 1
9
+ if session.tree_connect_table.length >= MAX_TREE_CONNECTIONS
10
+ logger.warn('Connection has reached the maximum number of tree connections')
11
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_INSUFFICIENT_RESOURCES
12
+ return response
13
+ end
14
+
15
+ share_name = request.path.encode('UTF-8').split('\\', 4).last
16
+ share_provider = @server.shares[share_name]
17
+
18
+ if share_provider.nil?
19
+ logger.warn("Received TREE_CONNECT request for non-existent share: #{share_name}")
20
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_BAD_NETWORK_NAME
21
+ return response
22
+ end
23
+ logger.debug("Received TREE_CONNECT request for share: #{share_name}")
24
+
25
+ response.share_type = case share_provider.type
26
+ when Share::TYPE_DISK
27
+ RubySMB::SMB2::Packet::TreeConnectResponse::SMB2_SHARE_TYPE_DISK
28
+ when Share::TYPE_PIPE
29
+ RubySMB::SMB2::Packet::TreeConnectResponse::SMB2_SHARE_TYPE_PIPE
30
+ when Share::TYPE_PRINT
31
+ RubySMB::SMB2::Packet::TreeConnectResponse::SMB2_SHARE_TYPE_PRINT
32
+ end
33
+
34
+ tree_id = rand(0xffffffff)
35
+ tree_id = rand(0xffffffff) while session.tree_connect_table.include?(tree_id)
36
+
37
+ response.smb2_header.tree_id = tree_id
38
+ session.tree_connect_table[tree_id] = share_processor = share_provider.new_processor(self, session)
39
+ response.maximal_access = share_processor.maximal_access
40
+
41
+ response
42
+ end
43
+
44
+ def do_tree_disconnect_smb2(request, session)
45
+ share_processor = session.tree_connect_table.delete(request.smb2_header.tree_id)
46
+ if share_processor.nil?
47
+ response = SMB2::Packet::ErrorPacket.new
48
+ response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NETWORK_NAME_DELETED
49
+ return response
50
+ end
51
+
52
+ logger.debug("Received TREE_DISCONNECT request for share: #{share_processor.provider.name}")
53
+ share_processor.disconnect!
54
+ response = RubySMB::SMB2::Packet::TreeDisconnectResponse.new
55
+ response
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end