ruby_smb 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/verify.yml +46 -0
  4. data/README.md +0 -1
  5. data/examples/anonymous_auth.rb +3 -3
  6. data/examples/append_file.rb +10 -8
  7. data/examples/auth_capture.rb +71 -0
  8. data/examples/authenticate.rb +9 -5
  9. data/examples/delete_file.rb +8 -6
  10. data/examples/dump_secrets_from_sid.rb +207 -0
  11. data/examples/enum_domain_users.rb +75 -0
  12. data/examples/enum_registry_key.rb +5 -4
  13. data/examples/enum_registry_values.rb +5 -4
  14. data/examples/get_computer_info.rb +42 -0
  15. data/examples/list_directory.rb +8 -6
  16. data/examples/negotiate_with_netbios_service.rb +9 -5
  17. data/examples/net_share_enum_all.rb +6 -4
  18. data/examples/pipes.rb +11 -12
  19. data/examples/query_service_status.rb +102 -0
  20. data/examples/read_file.rb +8 -6
  21. data/examples/read_registry_key_value.rb +6 -5
  22. data/examples/rename_file.rb +9 -7
  23. data/examples/tree_connect.rb +7 -5
  24. data/examples/write_file.rb +9 -7
  25. data/lib/ruby_smb/client/authentication.rb +5 -10
  26. data/lib/ruby_smb/client/echo.rb +2 -4
  27. data/lib/ruby_smb/client/negotiation.rb +13 -16
  28. data/lib/ruby_smb/client/tree_connect.rb +2 -4
  29. data/lib/ruby_smb/client/utils.rb +16 -10
  30. data/lib/ruby_smb/client/winreg.rb +1 -1
  31. data/lib/ruby_smb/client.rb +102 -75
  32. data/lib/ruby_smb/compression/lznt1.rb +164 -0
  33. data/lib/ruby_smb/compression.rb +7 -0
  34. data/lib/ruby_smb/dcerpc/bind.rb +28 -20
  35. data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
  36. data/lib/ruby_smb/dcerpc/client.rb +542 -0
  37. data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
  38. data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
  39. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
  40. data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
  41. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
  42. data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
  43. data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
  44. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
  45. data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
  46. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
  47. data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
  48. data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
  49. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
  50. data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
  51. data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
  52. data/lib/ruby_smb/dcerpc/epm.rb +75 -0
  53. data/lib/ruby_smb/dcerpc/error.rb +20 -0
  54. data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
  55. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
  56. data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
  57. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
  58. data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
  59. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
  60. data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
  61. data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
  62. data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
  63. data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
  64. data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
  65. data/lib/ruby_smb/dcerpc/request.rb +85 -19
  66. data/lib/ruby_smb/dcerpc/response.rb +45 -10
  67. data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
  68. data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
  69. data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
  70. data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
  71. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
  72. data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
  73. data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
  74. data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
  75. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
  76. data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
  77. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
  78. data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
  79. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
  80. data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
  81. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
  82. data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
  83. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
  84. data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
  85. data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
  86. data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
  87. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
  88. data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
  89. data/lib/ruby_smb/dcerpc/samr.rb +613 -0
  90. data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
  91. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
  92. data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
  93. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +36 -0
  94. data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
  95. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
  96. data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
  97. data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
  98. data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
  99. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
  100. data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
  101. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
  102. data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
  103. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
  104. data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
  105. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
  106. data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
  107. data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
  108. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
  109. data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
  110. data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
  111. data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
  112. data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
  113. data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +62 -0
  114. data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
  115. data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
  116. data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
  117. data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
  118. data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
  119. data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
  120. data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
  121. data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +6 -7
  122. data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
  123. data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
  124. data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
  125. data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
  126. data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
  127. data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
  128. data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +28 -0
  129. data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
  130. data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
  131. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
  132. data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
  133. data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
  134. data/lib/ruby_smb/dcerpc.rb +45 -11
  135. data/lib/ruby_smb/dialect.rb +45 -0
  136. data/lib/ruby_smb/dispatcher/base.rb +1 -1
  137. data/lib/ruby_smb/dispatcher/socket.rb +2 -2
  138. data/lib/ruby_smb/error.rb +21 -5
  139. data/lib/ruby_smb/field/file_time.rb +1 -1
  140. data/lib/ruby_smb/field/string16.rb +5 -1
  141. data/lib/ruby_smb/field/stringz16.rb +17 -1
  142. data/lib/ruby_smb/generic_packet.rb +11 -1
  143. data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
  144. data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
  145. data/lib/ruby_smb/gss/provider.rb +35 -0
  146. data/lib/ruby_smb/gss.rb +56 -63
  147. data/lib/ruby_smb/nbss/session_header.rb +4 -4
  148. data/lib/ruby_smb/ntlm.rb +61 -0
  149. data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
  150. data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
  151. data/lib/ruby_smb/server/server_client.rb +162 -0
  152. data/lib/ruby_smb/server.rb +54 -0
  153. data/lib/ruby_smb/signing.rb +59 -0
  154. data/lib/ruby_smb/smb1/file.rb +10 -25
  155. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
  156. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
  157. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
  158. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
  159. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
  160. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
  161. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
  162. data/lib/ruby_smb/smb1/pipe.rb +12 -6
  163. data/lib/ruby_smb/smb1/tree.rb +13 -9
  164. data/lib/ruby_smb/smb2/file.rb +33 -33
  165. data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
  166. data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
  167. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
  168. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
  169. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
  170. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
  171. data/lib/ruby_smb/smb2/pipe.rb +13 -6
  172. data/lib/ruby_smb/smb2/tree.rb +21 -11
  173. data/lib/ruby_smb/smb2.rb +3 -1
  174. data/lib/ruby_smb/version.rb +1 -1
  175. data/lib/ruby_smb.rb +5 -3
  176. data/spec/lib/ruby_smb/client_spec.rb +199 -86
  177. data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
  178. data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
  179. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
  180. data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
  181. data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
  182. data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3977 -239
  183. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
  184. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
  185. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
  186. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
  187. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
  188. data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
  189. data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
  190. data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
  191. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
  192. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
  193. data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
  194. data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +162 -0
  195. data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
  196. data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
  197. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
  198. data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
  199. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
  200. data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
  201. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
  202. data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
  203. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
  204. data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
  205. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
  206. data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
  207. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
  208. data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
  209. data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
  210. data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
  211. data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
  212. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
  213. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +168 -0
  214. data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
  215. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
  216. data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
  217. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
  218. data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
  219. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
  220. data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
  221. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
  222. data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
  223. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
  224. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
  225. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
  226. data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
  227. data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
  228. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
  229. data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
  230. data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
  231. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
  232. data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
  233. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +73 -0
  234. data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
  235. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
  236. data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
  237. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
  238. data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
  239. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
  240. data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
  241. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -20
  242. data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
  243. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
  244. data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
  245. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
  246. data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +18 -42
  247. data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
  248. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
  249. data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
  250. data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
  251. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
  252. data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
  253. data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
  254. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
  255. data/spec/lib/ruby_smb/error_spec.rb +34 -5
  256. data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
  257. data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
  258. data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
  259. data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
  260. data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
  261. data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
  262. data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
  263. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
  264. data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
  265. data/spec/lib/ruby_smb/server_spec.rb +32 -0
  266. data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
  267. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
  268. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
  269. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
  270. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
  271. data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
  272. data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
  273. data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
  274. data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
  275. data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
  276. data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
  277. data/spec/spec_helper.rb +1 -1
  278. data/spec/support/bin_helper.rb +9 -0
  279. data.tar.gz.sig +0 -0
  280. metadata +229 -23
  281. metadata.gz.sig +0 -0
  282. data/.travis.yml +0 -6
  283. data/lib/ruby_smb/client/signing.rb +0 -64
  284. data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
  285. data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
@@ -0,0 +1,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
@@ -102,26 +102,26 @@ RSpec.describe RubySMB::Dispatcher::Socket do
102
102
  end
103
103
 
104
104
  it 'reads the number of bytes specified in the nbss header' do
105
- packet_length = 10
106
- session_header.packet_length = packet_length
105
+ stream_protocol_length = 10
106
+ session_header.stream_protocol_length = stream_protocol_length
107
107
  allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
108
108
  expect(response_socket).to receive(:read).with(4).and_return(session_header)
109
- expect(response_socket).to receive(:read).with(packet_length).and_return('A' * packet_length)
109
+ expect(response_socket).to receive(:read).with(stream_protocol_length).and_return('A' * stream_protocol_length)
110
110
  smb_socket.recv_packet
111
111
  end
112
112
 
113
113
  context 'when the socket does not return everything the first time' do
114
114
  it 'calls #read several times until everything is returned' do
115
- packet_length = 67
115
+ stream_protocol_length = 67
116
116
  returned_length = 10
117
- session_header.packet_length = packet_length
117
+ session_header.stream_protocol_length = stream_protocol_length
118
118
  allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
119
119
 
120
120
  expect(response_socket).to receive(:read).with(4).and_return(session_header)
121
121
  loop do
122
- expect(response_socket).to receive(:read).with(packet_length).and_return('A' * returned_length).once
123
- packet_length -= returned_length
124
- break if packet_length <= 0
122
+ expect(response_socket).to receive(:read).with(stream_protocol_length).and_return('A' * returned_length).once
123
+ stream_protocol_length -= returned_length
124
+ break if stream_protocol_length <= 0
125
125
  end
126
126
  smb_socket.recv_packet
127
127
  end
@@ -134,7 +134,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
134
134
 
135
135
  context 'when the SMB packet is empty' do
136
136
  it 'returns the nbss header only' do
137
- session_header.packet_length = 0
137
+ session_header.stream_protocol_length = 0
138
138
  allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
139
139
  expect(smb_socket.recv_packet(full_response: true)).to eq(session_header.to_binary_s)
140
140
  end
@@ -148,7 +148,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
148
148
 
149
149
  context 'when the SMB packet is empty' do
150
150
  it 'returns an empty string' do
151
- session_header.packet_length = 0
151
+ session_header.stream_protocol_length = 0
152
152
  allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
153
153
  expect(smb_socket.recv_packet(full_response: false)).to eq('')
154
154
  end
@@ -9,16 +9,45 @@ RSpec.describe RubySMB::Error::InvalidPacket do
9
9
  end
10
10
 
11
11
  context 'with a Hash' do
12
- it 'outputs the expected error message' do
13
- ex = described_class.new(
12
+ let(:ex) do
13
+ described_class.new(
14
14
  expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
15
15
  expected_cmd: RubySMB::SMB1::Packet::NegotiateResponseExtended::COMMAND,
16
16
  expected_custom: "extended_security=1",
17
- received_proto: RubySMB::SMB2::SMB2_PROTOCOL_ID,
18
- received_cmd: RubySMB::SMB2::Packet::NegotiateResponse::COMMAND,
17
+ packet: packet,
19
18
  received_custom: "extended_security=0"
20
19
  )
21
- expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB2 protocol with command=0 (extended_security=0)')
20
+ end
21
+
22
+ context 'with an SMB2 packet' do
23
+ let(:packet) { RubySMB::SMB2::Packet::NegotiateResponse.new }
24
+
25
+ it 'outputs the expected error message' do
26
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB2 protocol with command=0 (extended_security=0), Status: (0x00000000) STATUS_SUCCESS: The operation completed successfully.')
27
+ end
28
+ end
29
+
30
+ context 'with an SMB1 packet' do
31
+ let(:packet) { RubySMB::SMB1::Packet::ReadAndxRequest.new }
32
+
33
+ it 'outputs the expected error message' do
34
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got SMB1 protocol with command=46 (extended_security=0), Status: (0x00000000) STATUS_SUCCESS: The operation completed successfully.')
35
+ end
36
+ end
37
+
38
+ context 'without packet' do
39
+ let(:ex) do
40
+ described_class.new(
41
+ expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
42
+ expected_cmd: RubySMB::SMB1::Packet::NegotiateResponseExtended::COMMAND,
43
+ expected_custom: "extended_security=1",
44
+ received_custom: "extended_security=0"
45
+ )
46
+ end
47
+
48
+ it 'outputs the expected error message' do
49
+ expect(ex.to_s).to eq('Expecting SMB1 protocol with command=114 (extended_security=1), got ??? protocol with command=??? (extended_security=0)')
50
+ end
22
51
  end
23
52
  end
24
53
 
@@ -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
@@ -44,5 +44,17 @@ RSpec.describe RubySMB::Field::Stringz16 do
44
44
  io = StringIO.new("A\x00B\x00C\x00D\x00")
45
45
  expect { stringz16.read(io) }.to raise_error(EOFError)
46
46
  end
47
+
48
+ it 'trims the string to #max_length and makes sure it ends with a null terminator' do
49
+ io = StringIO.new("A\x00B\x00C\x00D\x00")
50
+ str = described_class.new(max_length: 6)
51
+ expect(str.read(io).to_binary_s).to eq("A\x00B\x00\x00\x00".b)
52
+ end
53
+
54
+ it 'raises an exception when #max_length is not a multiple of two' do
55
+ io = StringIO.new("A\x00B\x00C\x00D\x00")
56
+ str = described_class.new(max_length: 5)
57
+ expect { str.read(io) }.to raise_error(ArgumentError)
58
+ end
47
59
  end
48
60
  end
@@ -88,6 +88,13 @@ RSpec.describe RubySMB::GenericPacket do
88
88
  packet = RubySMB::SMB2::Packet::NegotiateResponse.read(smb2_error_packet.to_binary_s)
89
89
  expect(packet.original_command).to eq RubySMB::SMB2::Packet::NegotiateResponse::COMMAND
90
90
  end
91
+
92
+ context 'when the server returns an SMB1 error packet' do
93
+ let(:smb1_error_packet) { RubySMB::SMB1::Packet::EmptyPacket.new }
94
+ it 'returns the empty packet instead of the asked for class' do
95
+ expect(RubySMB::SMB2::Packet::NegotiateResponse.read(smb1_error_packet.to_binary_s)).to be_a RubySMB::SMB1::Packet::EmptyPacket
96
+ end
97
+ end
91
98
  end
92
99
  end
93
100
 
@@ -0,0 +1,32 @@
1
+ RSpec.describe RubySMB::Gss::Provider::NTLM::Account do
2
+ let(:username) { 'RubySMB' }
3
+ let(:password) { 'password' }
4
+ let(:domain) { 'WORKGROUP' }
5
+ subject(:account) { RubySMB::Gss::Provider::NTLM::Account.new(username, password, domain) }
6
+
7
+ it { is_expected.to respond_to :username }
8
+ it { is_expected.to respond_to :password }
9
+ it { is_expected.to respond_to :domain }
10
+
11
+ it 'sets the username correct' do
12
+ expect(account.username).to eq username
13
+ end
14
+
15
+ it 'sets the password correctly' do
16
+ expect(account.password).to eq password
17
+ end
18
+
19
+ it 'sets the domain correctly' do
20
+ expect(account.domain).to eq domain
21
+ end
22
+
23
+ describe '#to_s' do
24
+ it 'converts to a string' do
25
+ expect(account.to_s).to be_a String
26
+ end
27
+
28
+ it 'formats the username and domain correctly' do
29
+ expect(account.to_s).to eq "#{domain}\\#{username}"
30
+ end
31
+ end
32
+ end