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
@@ -0,0 +1,410 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkstaInfo102 do
2
+ subject(:packet) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :wki102_platform_id }
5
+ it { is_expected.to respond_to :wki102_computername }
6
+ it { is_expected.to respond_to :wki102_langroup }
7
+ it { is_expected.to respond_to :wki102_ver_major }
8
+ it { is_expected.to respond_to :wki102_ver_minor }
9
+ it { is_expected.to respond_to :wki102_lanroot }
10
+ it { is_expected.to respond_to :wki102_logged_on_users }
11
+
12
+ it 'is little endian' do
13
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
14
+ end
15
+ it 'it is a Ndr::NdrStruct' do
16
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrStruct
17
+ end
18
+ describe '#wki102_platform_id' do
19
+ it 'is a NdrUint32 structure' do
20
+ expect(packet.wki102_platform_id).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
21
+ end
22
+ end
23
+ describe '#wki102_computername' do
24
+ it 'is a Ndr::NdrWideStringzPtr' do
25
+ expect(packet.wki102_computername).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
26
+ end
27
+ end
28
+ describe '#wki102_langroup' do
29
+ it 'is a Ndr::NdrWideStringzPtr' do
30
+ expect(packet.wki102_langroup).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
31
+ end
32
+ end
33
+ describe '#wki102_ver_major' do
34
+ it 'is a NdrUint32 structure' do
35
+ expect(packet.wki102_ver_major).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
36
+ end
37
+ end
38
+ describe '#wki102_ver_minor' do
39
+ it 'is a NdrUint32 structure' do
40
+ expect(packet.wki102_ver_minor).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
41
+ end
42
+ end
43
+ describe '#wki102_lanroot' do
44
+ it 'is a Ndr::NdrWideStringzPtr' do
45
+ expect(packet.wki102_lanroot).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
46
+ end
47
+ end
48
+ describe '#wki102_logged_on_users' do
49
+ it 'is a NdrUint32 structure' do
50
+ expect(packet.wki102_logged_on_users).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
51
+ end
52
+ end
53
+ it 'reads itself' do
54
+ new_class = described_class.new(
55
+ wki102_platform_id: 500,
56
+ wki102_computername: 'MYCOMPUTER',
57
+ wki102_langroup: 'MYDOMAIN',
58
+ wki102_ver_major: 6,
59
+ wki102_ver_minor: 2,
60
+ wki102_lanroot: 'MYLANROOT',
61
+ wki102_logged_on_users: 4,
62
+ )
63
+ expect(packet.read(new_class.to_binary_s)).to eq(
64
+ {
65
+ wki102_platform_id: 500,
66
+ wki102_computername: 'MYCOMPUTER'.encode('utf-16le'),
67
+ wki102_langroup: 'MYDOMAIN'.encode('utf-16le'),
68
+ wki102_ver_major: 6,
69
+ wki102_ver_minor: 2,
70
+ wki102_lanroot: 'MYLANROOT'.encode('utf-16le'),
71
+ wki102_logged_on_users: 4,
72
+ }
73
+ )
74
+ end
75
+ end
76
+
77
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::PwkstaInfo102 do
78
+ subject(:packet) { described_class.new }
79
+
80
+ it 'is a WkstaInfo102' do
81
+ expect(packet).to be_a(RubySMB::Dcerpc::Wkssvc::WkstaInfo102)
82
+ end
83
+ it 'is a NDR Pointer' do
84
+ expect(described_class).to be_a(RubySMB::Dcerpc::Ndr::PointerClassPlugin)
85
+ end
86
+ it 'reads itself' do
87
+ new_class = described_class.new(
88
+ wki102_platform_id: 500,
89
+ wki102_computername: 'MYCOMPUTER',
90
+ wki102_langroup: 'MYDOMAIN',
91
+ wki102_ver_major: 6,
92
+ wki102_ver_minor: 2,
93
+ wki102_lanroot: 'MYLANROOT',
94
+ wki102_logged_on_users: 4,
95
+ )
96
+ expect(packet.read(new_class.to_binary_s)).to eq(
97
+ {
98
+ wki102_platform_id: 500,
99
+ wki102_computername: 'MYCOMPUTER'.encode('utf-16le'),
100
+ wki102_langroup: 'MYDOMAIN'.encode('utf-16le'),
101
+ wki102_ver_major: 6,
102
+ wki102_ver_minor: 2,
103
+ wki102_lanroot: 'MYLANROOT'.encode('utf-16le'),
104
+ wki102_logged_on_users: 4,
105
+ }
106
+ )
107
+ end
108
+ end
109
+
110
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkstaInfo101 do
111
+ subject(:packet) { described_class.new }
112
+
113
+ it { is_expected.to respond_to :wki101_platform_id }
114
+ it { is_expected.to respond_to :wki101_computername }
115
+ it { is_expected.to respond_to :wki101_langroup }
116
+ it { is_expected.to respond_to :wki101_ver_major }
117
+ it { is_expected.to respond_to :wki101_ver_minor }
118
+ it { is_expected.to respond_to :wki101_lanroot }
119
+
120
+ it 'is little endian' do
121
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
122
+ end
123
+ it 'it is a Ndr::NdrStruct' do
124
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrStruct
125
+ end
126
+ describe '#wki101_platform_id' do
127
+ it 'is a NdrUint32 structure' do
128
+ expect(packet.wki101_platform_id).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
129
+ end
130
+ end
131
+ describe '#wki101_computername' do
132
+ it 'is a Ndr::NdrWideStringzPtr' do
133
+ expect(packet.wki101_computername).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
134
+ end
135
+ end
136
+ describe '#wki101_langroup' do
137
+ it 'is a Ndr::NdrWideStringzPtr' do
138
+ expect(packet.wki101_langroup).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
139
+ end
140
+ end
141
+ describe '#wki101_ver_major' do
142
+ it 'is a NdrUint32 structure' do
143
+ expect(packet.wki101_ver_major).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
144
+ end
145
+ end
146
+ describe '#wki101_ver_minor' do
147
+ it 'is a NdrUint32 structure' do
148
+ expect(packet.wki101_ver_minor).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
149
+ end
150
+ end
151
+ describe '#wki101_lanroot' do
152
+ it 'is a Ndr::NdrWideStringzPtr' do
153
+ expect(packet.wki101_lanroot).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
154
+ end
155
+ end
156
+ it 'reads itself' do
157
+ new_class = described_class.new(
158
+ wki101_platform_id: 500,
159
+ wki101_computername: 'MYCOMPUTER',
160
+ wki101_langroup: 'MYDOMAIN',
161
+ wki101_ver_major: 6,
162
+ wki101_ver_minor: 2,
163
+ wki101_lanroot: 'MYLANROOT'
164
+ )
165
+ expect(packet.read(new_class.to_binary_s)).to eq(
166
+ {
167
+ wki101_platform_id: 500,
168
+ wki101_computername: 'MYCOMPUTER'.encode('utf-16le'),
169
+ wki101_langroup: 'MYDOMAIN'.encode('utf-16le'),
170
+ wki101_ver_major: 6,
171
+ wki101_ver_minor: 2,
172
+ wki101_lanroot: 'MYLANROOT'.encode('utf-16le')
173
+ }
174
+ )
175
+ end
176
+ end
177
+
178
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::PwkstaInfo101 do
179
+ subject(:packet) { described_class.new }
180
+
181
+ it 'is a WkstaInfo101' do
182
+ expect(packet).to be_a(RubySMB::Dcerpc::Wkssvc::WkstaInfo101)
183
+ end
184
+ it 'is a NDR Pointer' do
185
+ expect(described_class).to be_a(RubySMB::Dcerpc::Ndr::PointerClassPlugin)
186
+ end
187
+ it 'reads itself' do
188
+ new_class = described_class.new(
189
+ wki101_platform_id: 500,
190
+ wki101_computername: 'MYCOMPUTER',
191
+ wki101_langroup: 'MYDOMAIN',
192
+ wki101_ver_major: 6,
193
+ wki101_ver_minor: 2,
194
+ wki101_lanroot: 'MYLANROOT'
195
+ )
196
+ expect(packet.read(new_class.to_binary_s)).to eq(
197
+ {
198
+ wki101_platform_id: 500,
199
+ wki101_computername: 'MYCOMPUTER'.encode('utf-16le'),
200
+ wki101_langroup: 'MYDOMAIN'.encode('utf-16le'),
201
+ wki101_ver_major: 6,
202
+ wki101_ver_minor: 2,
203
+ wki101_lanroot: 'MYLANROOT'.encode('utf-16le')
204
+ }
205
+ )
206
+ end
207
+ end
208
+
209
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::WkstaInfo100 do
210
+ subject(:packet) { described_class.new }
211
+
212
+ it { is_expected.to respond_to :wki100_platform_id }
213
+ it { is_expected.to respond_to :wki100_computername }
214
+ it { is_expected.to respond_to :wki100_langroup }
215
+ it { is_expected.to respond_to :wki100_ver_major }
216
+ it { is_expected.to respond_to :wki100_ver_minor }
217
+
218
+ it 'is little endian' do
219
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
220
+ end
221
+ it 'it is a Ndr::NdrStruct' do
222
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrStruct
223
+ end
224
+ describe '#wki100_platform_id' do
225
+ it 'is a NdrUint32 structure' do
226
+ expect(packet.wki100_platform_id).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
227
+ end
228
+ end
229
+ describe '#wki100_computername' do
230
+ it 'is a Ndr::NdrWideStringzPtr' do
231
+ expect(packet.wki100_computername).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
232
+ end
233
+ end
234
+ describe '#wki100_langroup' do
235
+ it 'is a Ndr::NdrWideStringzPtr' do
236
+ expect(packet.wki100_langroup).to be_a(RubySMB::Dcerpc::Ndr::NdrWideStringzPtr)
237
+ end
238
+ end
239
+ describe '#wki100_ver_major' do
240
+ it 'is a NdrUint32 structure' do
241
+ expect(packet.wki100_ver_major).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
242
+ end
243
+ end
244
+ describe '#wki100_ver_minor' do
245
+ it 'is a NdrUint32 structure' do
246
+ expect(packet.wki100_ver_minor).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
247
+ end
248
+ end
249
+
250
+ it 'reads itself' do
251
+ new_class = described_class.new(
252
+ wki100_platform_id: 500,
253
+ wki100_computername: 'MYCOMPUTER',
254
+ wki100_langroup: 'MYDOMAIN',
255
+ wki100_ver_major: 6,
256
+ wki100_ver_minor: 2
257
+ )
258
+ expect(packet.read(new_class.to_binary_s)).to eq(
259
+ {
260
+ wki100_platform_id: 500,
261
+ wki100_computername: 'MYCOMPUTER'.encode('utf-16le'),
262
+ wki100_langroup: 'MYDOMAIN'.encode('utf-16le'),
263
+ wki100_ver_major: 6,
264
+ wki100_ver_minor: 2
265
+ }
266
+ )
267
+ end
268
+ end
269
+
270
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::PwkstaInfo100 do
271
+ subject(:packet) { described_class.new }
272
+
273
+ it 'is a WkstaInfo100' do
274
+ expect(packet).to be_a(RubySMB::Dcerpc::Wkssvc::WkstaInfo100)
275
+ end
276
+ it 'is a NDR Pointer' do
277
+ expect(described_class).to be_a(RubySMB::Dcerpc::Ndr::PointerClassPlugin)
278
+ end
279
+ it 'reads itself' do
280
+ new_class = described_class.new(
281
+ wki100_platform_id: 500,
282
+ wki100_computername: 'MYCOMPUTER',
283
+ wki100_langroup: 'MYDOMAIN',
284
+ wki100_ver_major: 6,
285
+ wki100_ver_minor: 2
286
+ )
287
+ expect(packet.read(new_class.to_binary_s)).to eq(
288
+ {
289
+ wki100_platform_id: 500,
290
+ wki100_computername: 'MYCOMPUTER'.encode('utf-16le'),
291
+ wki100_langroup: 'MYDOMAIN'.encode('utf-16le'),
292
+ wki100_ver_major: 6,
293
+ wki100_ver_minor: 2
294
+ }
295
+ )
296
+ end
297
+ end
298
+
299
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::LpwkstaInfo do
300
+ subject(:packet) { described_class.new }
301
+
302
+ it { is_expected.to respond_to :level }
303
+ it { is_expected.to respond_to :info }
304
+
305
+ it 'is little endian' do
306
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
307
+ end
308
+ it 'it is a Ndr::NdrStruct' do
309
+ expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrStruct
310
+ end
311
+ describe '#level' do
312
+ it 'is a NdrUint32 structure' do
313
+ expect(packet.level).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
314
+ end
315
+ end
316
+ describe '#info' do
317
+ it 'is a BinData:Choice structure' do
318
+ expect(packet.info).to be_a BinData::Choice
319
+ end
320
+ it 'selects a structure according to :level value' do
321
+ packet.level = RubySMB::Dcerpc::Wkssvc::WKSTA_INFO_100
322
+ expect(packet.info.send(:current_choice)).to be_a(RubySMB::Dcerpc::Wkssvc::WkstaInfo100)
323
+ end
324
+ end
325
+ it 'reads itself' do
326
+ new_class = described_class.new(
327
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_INFO_100,
328
+ info: {
329
+ wki100_platform_id: 500,
330
+ wki100_computername: 'MYCOMPUTER',
331
+ wki100_langroup: 'MYDOMAIN',
332
+ wki100_ver_major: 6,
333
+ wki100_ver_minor: 2
334
+ }
335
+ )
336
+ expect(packet.read(new_class.to_binary_s)).to eq(
337
+ {
338
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_INFO_100,
339
+ info: {
340
+ wki100_platform_id: 500,
341
+ wki100_computername: 'MYCOMPUTER'.encode('utf-16le'),
342
+ wki100_langroup: 'MYDOMAIN'.encode('utf-16le'),
343
+ wki100_ver_major: 6,
344
+ wki100_ver_minor: 2
345
+ }
346
+ }
347
+ )
348
+ end
349
+ end
350
+
351
+ RSpec.describe RubySMB::Dcerpc::Wkssvc::NetrWkstaGetInfoResponse do
352
+ subject(:packet) { described_class.new }
353
+
354
+ it { is_expected.to respond_to :wksta_info }
355
+ it { is_expected.to respond_to :error_status }
356
+ it { is_expected.to respond_to :opnum }
357
+
358
+ it 'is little endian' do
359
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
360
+ end
361
+ it 'is a BinData::Record' do
362
+ expect(packet).to be_a(BinData::Record)
363
+ end
364
+ describe '#wksta_info' do
365
+ it 'is a LpwkstaInfo structure' do
366
+ expect(packet.wksta_info).to be_a RubySMB::Dcerpc::Wkssvc::LpwkstaInfo
367
+ end
368
+ end
369
+ describe '#error_status' do
370
+ it 'is a NdrUint32 structure' do
371
+ expect(packet.error_status).to be_a RubySMB::Dcerpc::Ndr::NdrUint32
372
+ end
373
+ end
374
+ describe '#initialize_instance' do
375
+ it 'sets #opnum to NETR_WKSTA_GET_INFO constant' do
376
+ expect(packet.opnum).to eq(RubySMB::Dcerpc::Wkssvc::NETR_WKSTA_GET_INFO)
377
+ end
378
+ end
379
+ it 'reads itself' do
380
+ new_class = described_class.new(
381
+ wksta_info: {
382
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_INFO_100,
383
+ info: {
384
+ wki100_platform_id: 500,
385
+ wki100_computername: 'MYCOMPUTER',
386
+ wki100_langroup: 'MYDOMAIN',
387
+ wki100_ver_major: 6,
388
+ wki100_ver_minor: 2
389
+ }
390
+ },
391
+ error_status: 0
392
+ )
393
+ expect(packet.read(new_class.to_binary_s)).to eq(
394
+ {
395
+ wksta_info: {
396
+ level: RubySMB::Dcerpc::Wkssvc::WKSTA_INFO_100,
397
+ info: {
398
+ wki100_platform_id: 500,
399
+ wki100_computername: 'MYCOMPUTER'.encode('utf-16le'),
400
+ wki100_langroup: 'MYDOMAIN'.encode('utf-16le'),
401
+ wki100_ver_major: 6,
402
+ wki100_ver_minor: 2
403
+ }
404
+ },
405
+ error_status: 0
406
+ }
407
+ )
408
+ end
409
+ end
410
+
@@ -0,0 +1,70 @@
1
+ RSpec.describe RubySMB::Dcerpc::Wkssvc do
2
+ let(:wkssvc) do
3
+ RubySMB::SMB1::Pipe.new(
4
+ tree: double('Tree'),
5
+ response: RubySMB::SMB1::Packet::NtCreateAndxResponse.new,
6
+ name: 'wkssvc'
7
+ )
8
+ end
9
+
10
+ describe '#netr_wksta_get_info' do
11
+ let(:wkst_netr_wksta_get_info_request) { double('NetrWkstaGetInfoRequest') }
12
+ let(:response) { double('Response') }
13
+ let(:wkst_netr_wksta_get_info_response) { double('NetrWkstaGetInfoResponse') }
14
+ let(:info) { double('info') }
15
+ before :example do
16
+ allow(described_class::NetrWkstaGetInfoRequest).to receive(:new).and_return(wkst_netr_wksta_get_info_request)
17
+ allow(wkssvc).to receive(:dcerpc_request).and_return(response)
18
+ allow(described_class::NetrWkstaGetInfoResponse).to receive(:read).and_return(wkst_netr_wksta_get_info_response)
19
+ allow(wkst_netr_wksta_get_info_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
20
+ allow(wkst_netr_wksta_get_info_response).to receive_message_chain(:wksta_info, :info => info)
21
+ end
22
+
23
+ it 'sets the request with the expected values' do
24
+ wkssvc.netr_wksta_get_info
25
+ expect(described_class::NetrWkstaGetInfoRequest).to have_received(:new).with(
26
+ server_name: "\x00",
27
+ level: described_class::WKSTA_INFO_100
28
+ )
29
+ end
30
+ it 'send the expected request structure' do
31
+ wkssvc.netr_wksta_get_info
32
+ expect(wkssvc).to have_received(:dcerpc_request).with(wkst_netr_wksta_get_info_request)
33
+ end
34
+ context 'when an IOError occurs while parsing the response' do
35
+ it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
36
+ allow(described_class::NetrWkstaGetInfoResponse).to receive(:read).and_raise(IOError)
37
+ expect { wkssvc.netr_wksta_get_info }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
38
+ end
39
+ end
40
+ context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
41
+ it 'raises a RubySMB::Dcerpc::Error::WinregError' do
42
+ allow(wkst_netr_wksta_get_info_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
43
+ expect { wkssvc.netr_wksta_get_info }.to raise_error(RubySMB::Dcerpc::Error::WkssvcError)
44
+ end
45
+ end
46
+ it 'returns the expected handler' do
47
+ expect(wkssvc.netr_wksta_get_info).to eq(info)
48
+ end
49
+ context 'with a real binary stream' do
50
+ it 'returns the expected value' do
51
+ raw_response =
52
+ "d\x00\x00\x00\x00\x00\x02\x00\xF4\x01\x00\x00\x04\x00\x02\x00\b"\
53
+ "\x00\x02\x00\x06\x00\x00\x00\x02\x00\x00\x00\x0F\x00\x00\x00\x00"\
54
+ "\x00\x00\x00\x0F\x00\x00\x00W\x00I\x00N\x00-\x00A\x00B\x00C\x00D"\
55
+ "\x00E\x00F\x00C\x007\x006\x008\x00\x00\x00\x00\x00\x06\x00\x00"\
56
+ "\x00\x00\x00\x00\x00\x06\x00\x00\x00M\x00Y\x00L\x00A\x00B\x00\x00"\
57
+ "\x00\x00\x00\x00\x00"
58
+ allow(wkssvc).to receive(:dcerpc_request).and_return(raw_response)
59
+ allow(described_class::NetrWkstaGetInfoResponse).to receive(:read).and_call_original
60
+ expect(wkssvc.netr_wksta_get_info).to eq({
61
+ wki100_platform_id: 500,
62
+ wki100_computername: "WIN-ABCDEFC768".encode('utf-16le'),
63
+ wki100_langroup: "MYLAB".encode('utf-16le'),
64
+ wki100_ver_major: 6,
65
+ wki100_ver_minor: 2
66
+ })
67
+ end
68
+ end
69
+ end
70
+ end
@@ -3,8 +3,12 @@ RSpec.describe RubySMB::Field::NtStatus do
3
3
 
4
4
  it { is_expected.to respond_to :to_nt_status }
5
5
 
6
- it 'is a Unsigned 32-bit little endian integer' do
7
- expect(nt_status).to be_a BinData::Uint32le
6
+ it 'uses an internal Unsigned 32-bit little endian integer' do
7
+ expect(nt_status.val).to be_a BinData::Uint32le
8
+ end
9
+
10
+ it 'returns an integer value' do
11
+ expect(nt_status.value).to be_a Integer
8
12
  end
9
13
 
10
14
  describe '#to_nt_status' do
@@ -0,0 +1,22 @@
1
+ RSpec.describe RubySMB::Field::String16 do
2
+ subject(:field) { described_class.new }
3
+
4
+ it 'is a BinData::String' do
5
+ expect(field).to be_a BinData::String
6
+ end
7
+
8
+ it 'converts to utf-16le when assigning a String' do
9
+ expect(field.assign('Test'.encode('ASCII-8BIT')).encoding).to be Encoding::UTF_16LE
10
+ end
11
+
12
+ it 'makes sure snapshot returns a utf-16le string' do
13
+ field.new('Test'.encode('ASCII-8BIT'))
14
+ expect(field.snapshot.encoding).to be Encoding::UTF_16LE
15
+ end
16
+
17
+ it 'makes sure read operation returns a utf-16le string' do
18
+ field.read('Test'.encode('ASCII-8BIT'))
19
+ expect(field.snapshot.encoding).to be Encoding::UTF_16LE
20
+ end
21
+
22
+ end
@@ -13,6 +13,10 @@ RSpec.describe RubySMB::Gss::Provider::NTLM::Authenticator do
13
13
  Net::NTLM::Message::Type2.new.response(user: username, password: '', domain: domain)
14
14
  end
15
15
 
16
+ before(:each) do
17
+ allow(authenticator).to receive(:logger).and_return(Logger.new(IO::NULL))
18
+ end
19
+
16
20
  describe '#initialize' do
17
21
  it 'defaults to a null session key' do
18
22
  expect(authenticator.session_key).to be_nil
@@ -15,7 +15,7 @@ RSpec.describe RubySMB::Gss::Provider::NTLM::OSVersion do
15
15
  describe '#read' do
16
16
  it 'reads a packed version correctly' do
17
17
  # Version 6.1 (Build 7601); NTLM Current Revision 15
18
- os_version = RubySMB::Gss::Provider::NTLM::OSVersion.read("\x06\x01\x1d\xb1\x00\x00\x00\x0f")
18
+ os_version = RubySMB::Gss::Provider::NTLM::OSVersion.read("\x06\x01\xb1\x1d\x00\x00\x00\x0f")
19
19
  expect(os_version.major).to eq 6
20
20
  expect(os_version.minor).to eq 1
21
21
  expect(os_version.build).to eq 7601
@@ -5,33 +5,24 @@ RSpec.describe RubySMB::Server::ServerClient do
5
5
  subject(:server_client) { described_class.new(server, dispatcher) }
6
6
 
7
7
  it { is_expected.to respond_to :dialect }
8
- it { is_expected.to respond_to :identity }
9
- it { is_expected.to respond_to :state }
10
- it { is_expected.to respond_to :session_key }
8
+ it { is_expected.to respond_to :session_table }
11
9
 
12
10
  describe '#disconnect!' do
13
11
  it 'closes the socket' do
12
+ expect(dispatcher.tcp_socket).to receive(:closed?).with(no_args).and_return(false)
14
13
  expect(dispatcher.tcp_socket).to receive(:close).with(no_args).and_return(nil)
15
14
  server_client.disconnect!
16
15
  end
17
16
  end
18
17
 
19
18
  describe '#initialize' do
20
- it 'starts in the negotiate state' do
21
- expect(server_client.state).to eq :negotiate
22
- end
23
-
24
19
  it 'starts without a dialect' do
25
20
  expect(server_client.dialect).to be_nil
26
21
  expect(server_client.metadialect).to be_nil
27
22
  end
28
23
 
29
- it 'starts without an identity' do
30
- expect(server_client.identity).to be_nil
31
- end
32
-
33
- it 'starts without a session_key' do
34
- expect(server_client.session_key).to be_nil
24
+ it 'starts without any sessions' do
25
+ expect(server_client.session_table).to be_empty
35
26
  end
36
27
 
37
28
  it 'creates a new authenticator instance' do
@@ -66,33 +57,30 @@ RSpec.describe RubySMB::Server::ServerClient do
66
57
  before(:each) do
67
58
  expect(server_client).to receive(:recv_packet).and_return(packet)
68
59
  # this hook should ensure that the dispatcher loop returns after processing a single request
69
- expect(dispatcher.tcp_socket).to receive(:closed?).and_return(true)
60
+ expect(dispatcher.tcp_socket).to receive(:closed?).with(no_args).and_return(true)
61
+ expect(server_client).to receive(:disconnect!).with(no_args).and_return(nil)
70
62
  end
71
63
 
72
- it 'calls #handle_negotiate when the state is negotiate' do
64
+ it 'calls #handle_negotiate when the dialect is nil' do
73
65
  expect(server_client).to receive(:handle_negotiate).with(packet).and_return(nil)
74
- server_client.instance_eval { @state = :negotiate }
75
- server_client.run
76
- end
77
-
78
- it 'calls #handle_session_setup when the state is session_setup' do
79
- expect(server_client).to receive(:handle_session_setup).with(packet).and_return(nil)
80
- server_client.instance_eval { @state = :session_setup }
66
+ server_client.instance_eval { @dialect = nil }
81
67
  server_client.run
82
68
  end
83
69
 
84
- it 'calls #authenticated when the state is authenticated' do
85
- expect(server_client).to receive(:handle_authenticated).with(packet).and_return(nil)
86
- server_client.instance_eval { @state = :authenticated }
70
+ it 'calls #handle_smb when the dialect is not nil' do
71
+ expect(server_client).to receive(:handle_smb).with(packet).and_return(nil)
72
+ server_client.instance_eval { @dialect = true }
87
73
  server_client.run
88
74
  end
89
75
  end
90
76
 
91
77
  describe '#send_packet' do
92
- let(:packet) { RubySMB::GenericPacket.new }
78
+ let(:session_id) { rand(0xffffffff) }
79
+ let(:packet) { RubySMB::SMB2::Packet::SessionSetupResponse.new(smb2_header: { session_id: session_id }) }
93
80
 
94
81
  before(:each) do
95
82
  expect(dispatcher).to receive(:send_packet).with(packet).and_return(nil)
83
+ server_client.session_table[session_id] = RubySMB::Server::Session.new(session_id)
96
84
  end
97
85
 
98
86
  it 'sends a packet to the dispatcher' do
@@ -105,40 +93,35 @@ RSpec.describe RubySMB::Server::ServerClient do
105
93
  server_client.instance_eval { @dialect = dialect }
106
94
  end
107
95
 
108
- context 'and the state is authenticated' do
96
+ context 'and the identity is anonymous' do
109
97
  before(:each) do
110
- server_client.instance_eval { @state = :authenticated }
98
+ server_client.session_table[session_id].user_id = RubySMB::Gss::Provider::IDENTITY_ANONYMOUS
111
99
  end
112
100
 
113
- context 'and the identity is anonymous' do
114
- before(:each) do
115
- server_client.instance_eval { @identity = RubySMB::Gss::Provider::IDENTITY_ANONYMOUS }
116
- end
117
-
118
- it 'does not sign packets' do
119
- expect(server_client).to_not receive(:smb2_sign)
120
- expect(server_client).to_not receive(:smb3_sign)
121
- server_client.send_packet(packet)
122
- end
101
+ it 'does not sign packets' do
102
+ expect(RubySMB::Signing).to_not receive(:smb2_sign)
103
+ expect(RubySMB::Signing).to_not receive(:smb3_sign)
104
+ server_client.send_packet(packet)
123
105
  end
106
+ end
124
107
 
125
- context 'and the identity is not anonymous' do
126
- before(:each) do
127
- server_client.instance_eval { @identity = 'WORKGROUP\RubySMB'; @session_key = Random.new.bytes(16) }
128
- end
108
+ context 'and the identity is not anonymous' do
109
+ before(:each) do
110
+ server_client.session_table[session_id].user_id = 'WORKGROUP\RubySMB'
111
+ server_client.session_table[session_id].key = Random.new.bytes(16)
112
+ end
129
113
 
130
- it 'does sign packets' do
131
- packet = RubySMB::GenericPacket.new
132
- dialect_family = RubySMB::Dialect[dialect].family
133
- if dialect_family == RubySMB::Dialect::FAMILY_SMB2
134
- expect(server_client).to receive(:smb2_sign).with(packet).and_return(packet)
135
- expect(server_client).to_not receive(:smb3_sign)
136
- elsif dialect_family == RubySMB::Dialect::FAMILY_SMB3
137
- expect(server_client).to receive(:smb3_sign).with(packet).and_return(packet)
138
- expect(server_client).to_not receive(:smb2_sign)
139
- end
140
- server_client.send_packet(packet)
114
+ it 'does sign packets' do
115
+ dialect_family = RubySMB::Dialect[dialect].family
116
+ session = server_client.session_table[session_id]
117
+ if dialect_family == RubySMB::Dialect::FAMILY_SMB2
118
+ expect(RubySMB::Signing).to receive(:smb2_sign).with(packet, session.key).and_return(packet)
119
+ expect(RubySMB::Signing).to_not receive(:smb3_sign)
120
+ elsif dialect_family == RubySMB::Dialect::FAMILY_SMB3
121
+ expect(RubySMB::Signing).to receive(:smb3_sign).with(packet, session.key, dialect, any_args).and_return(packet)
122
+ expect(RubySMB::Signing).to_not receive(:smb2_sign)
141
123
  end
124
+ server_client.send_packet(packet)
142
125
  end
143
126
  end
144
127
  end