ruby_smb 2.0.11 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +5 -16
  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/epm/epm_ept_map_request.rb +26 -0
  28. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  29. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  30. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  31. data/lib/ruby_smb/dcerpc/error.rb +17 -0
  32. data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
  33. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
  34. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
  35. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
  36. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
  37. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
  38. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
  39. data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
  40. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  41. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  42. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  43. data/lib/ruby_smb/dcerpc/request.rb +79 -32
  44. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  45. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  46. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +11 -11
  47. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  48. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  49. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  50. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  51. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  52. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  53. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  54. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  55. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  56. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  57. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  58. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  59. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  61. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  62. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  63. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  64. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  65. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  66. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  67. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  68. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  69. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  70. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  71. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +13 -25
  72. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
  73. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
  74. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
  75. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
  76. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
  77. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
  78. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
  79. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
  80. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
  81. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
  82. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
  83. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
  84. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
  85. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
  86. data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
  87. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  88. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  89. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +2 -13
  90. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
  91. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
  92. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  93. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  94. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  95. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  96. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  97. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +5 -6
  98. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  99. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  100. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
  101. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  102. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  103. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +0 -9
  104. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
  105. data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
  106. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  107. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  108. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  109. data/lib/ruby_smb/dcerpc.rb +41 -11
  110. data/lib/ruby_smb/field/file_time.rb +1 -1
  111. data/lib/ruby_smb/field/nt_status.rb +20 -1
  112. data/lib/ruby_smb/field/string16.rb +5 -1
  113. data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
  114. data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
  115. data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
  116. data/lib/ruby_smb/fscc/file_information.rb +29 -0
  117. data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
  118. data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
  119. data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
  120. data/lib/ruby_smb/fscc.rb +1 -0
  121. data/lib/ruby_smb/generic_packet.rb +6 -0
  122. data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
  123. data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
  124. data/lib/ruby_smb/ntlm.rb +18 -2
  125. data/lib/ruby_smb/server/server_client/negotiation.rb +1 -2
  126. data/lib/ruby_smb/server/server_client/session_setup.rb +44 -33
  127. data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
  128. data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
  129. data/lib/ruby_smb/server/server_client.rb +214 -25
  130. data/lib/ruby_smb/server/session.rb +71 -0
  131. data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
  132. data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
  133. data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
  134. data/lib/ruby_smb/server/share/provider.rb +38 -0
  135. data/lib/ruby_smb/server/share.rb +11 -0
  136. data/lib/ruby_smb/server.rb +35 -3
  137. data/lib/ruby_smb/signing.rb +37 -11
  138. data/lib/ruby_smb/smb1/commands.rb +4 -0
  139. data/lib/ruby_smb/smb1/pipe.rb +4 -0
  140. data/lib/ruby_smb/smb1.rb +0 -1
  141. data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
  142. data/lib/ruby_smb/smb2/commands.rb +4 -0
  143. data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
  144. data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
  145. data/lib/ruby_smb/smb2/create_context.rb +74 -22
  146. data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
  147. data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
  148. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
  149. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
  150. data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
  151. data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
  152. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
  153. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
  154. data/lib/ruby_smb/smb2/packet.rb +2 -0
  155. data/lib/ruby_smb/smb2/pipe.rb +4 -0
  156. data/lib/ruby_smb/smb2.rb +11 -0
  157. data/lib/ruby_smb/smb_error.rb +110 -0
  158. data/lib/ruby_smb/version.rb +1 -1
  159. data/lib/ruby_smb.rb +2 -0
  160. data/ruby_smb.gemspec +1 -1
  161. data/spec/lib/ruby_smb/client_spec.rb +1 -2
  162. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  163. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  164. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  165. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  166. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3792 -1373
  167. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
  168. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
  169. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
  170. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
  171. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  172. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  173. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  174. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  175. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  176. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +29 -28
  177. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  178. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  179. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  180. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  181. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  182. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  183. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  184. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  185. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  186. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  187. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  188. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  189. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  190. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  191. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  192. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  193. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  194. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  195. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +56 -79
  196. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
  197. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
  198. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
  199. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
  200. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
  201. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
  202. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
  203. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
  204. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
  205. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
  206. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
  207. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
  208. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
  209. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
  210. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
  211. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  212. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  213. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +4 -41
  214. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
  215. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
  216. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  217. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  218. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  219. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  220. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  221. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -25
  222. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  223. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  224. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  225. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +10 -22
  226. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  227. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
  228. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
  229. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
  230. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  231. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  232. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  233. data/spec/lib/ruby_smb/field/nt_status_spec.rb +6 -2
  234. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  235. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
  236. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
  237. data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
  238. data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
  239. data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
  240. data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
  241. data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
  242. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
  243. data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
  244. data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
  245. data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
  246. data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
  247. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
  248. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
  249. data/spec/support/bin_helper.rb +9 -0
  250. data.tar.gz.sig +2 -3
  251. metadata +129 -10
  252. metadata.gz.sig +0 -0
  253. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
  254. data/lib/ruby_smb/smb1/create_actions.rb +0 -20
  255. 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