ruby_smb 0.0.18 → 0.0.19

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 (298) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +247 -7
  5. data/examples/anonymous_auth.rb +6 -3
  6. data/examples/append_file.rb +40 -0
  7. data/examples/authenticate.rb +12 -7
  8. data/examples/delete_file.rb +40 -0
  9. data/examples/list_directory.rb +45 -0
  10. data/examples/negotiate.rb +0 -1
  11. data/examples/negotiate_with_netbios_service.rb +36 -0
  12. data/examples/net_share_enum_all.rb +30 -0
  13. data/examples/read_file.rb +39 -0
  14. data/examples/rename_file.rb +41 -0
  15. data/examples/tree_connect.rb +2 -4
  16. data/examples/write_file.rb +40 -0
  17. data/lib/ruby_smb.rb +5 -0
  18. data/lib/ruby_smb/client.rb +196 -43
  19. data/lib/ruby_smb/client/authentication.rb +89 -48
  20. data/lib/ruby_smb/client/echo.rb +1 -4
  21. data/lib/ruby_smb/client/negotiation.rb +46 -45
  22. data/lib/ruby_smb/client/signing.rb +9 -16
  23. data/lib/ruby_smb/client/tree_connect.rb +8 -13
  24. data/lib/ruby_smb/client/utils.rb +79 -0
  25. data/lib/ruby_smb/dcerpc.rb +30 -0
  26. data/lib/ruby_smb/dcerpc/bind.rb +60 -0
  27. data/lib/ruby_smb/dcerpc/handle.rb +60 -0
  28. data/lib/ruby_smb/dcerpc/ndr.rb +41 -0
  29. data/lib/ruby_smb/dcerpc/request.rb +43 -0
  30. data/lib/ruby_smb/dcerpc/response.rb +46 -0
  31. data/lib/ruby_smb/dcerpc/srvsvc.rb +17 -0
  32. data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +93 -0
  33. data/lib/ruby_smb/dcerpc/uuid.rb +28 -0
  34. data/lib/ruby_smb/dispatcher.rb +7 -3
  35. data/lib/ruby_smb/dispatcher/base.rb +23 -14
  36. data/lib/ruby_smb/dispatcher/socket.rb +71 -51
  37. data/lib/ruby_smb/dispositions.rb +32 -0
  38. data/lib/ruby_smb/error.rb +24 -18
  39. data/lib/ruby_smb/field.rb +5 -2
  40. data/lib/ruby_smb/field/extended_attribute_flag.rb +1 -1
  41. data/lib/ruby_smb/field/file_time.rb +3 -1
  42. data/lib/ruby_smb/field/security_descriptor.rb +6 -6
  43. data/lib/ruby_smb/field/smb2_fileid.rb +11 -0
  44. data/lib/ruby_smb/field/smb_fea.rb +3 -3
  45. data/lib/ruby_smb/field/smb_fea_list.rb +3 -3
  46. data/lib/ruby_smb/field/smb_gea.rb +12 -0
  47. data/lib/ruby_smb/field/smb_gea_list.rb +13 -0
  48. data/lib/ruby_smb/field/string16.rb +14 -0
  49. data/lib/ruby_smb/field/stringz16.rb +3 -7
  50. data/lib/ruby_smb/field/utime.rb +11 -10
  51. data/lib/ruby_smb/fscc.rb +12 -0
  52. data/lib/ruby_smb/fscc/control_codes.rb +26 -0
  53. data/lib/ruby_smb/{field → fscc}/ea_info_array.rb +12 -14
  54. data/lib/ruby_smb/fscc/file_attributes.rb +29 -0
  55. data/lib/ruby_smb/{field → fscc}/file_full_ea_info.rb +5 -5
  56. data/lib/ruby_smb/fscc/file_information.rb +60 -0
  57. data/lib/ruby_smb/fscc/file_information/file_both_directory_information.rb +29 -0
  58. data/lib/ruby_smb/fscc/file_information/file_directory_information.rb +25 -0
  59. data/lib/ruby_smb/fscc/file_information/file_disposition_information.rb +15 -0
  60. data/lib/ruby_smb/fscc/file_information/file_full_directory_information.rb +26 -0
  61. data/lib/ruby_smb/fscc/file_information/file_id_both_directory_information.rb +31 -0
  62. data/lib/ruby_smb/fscc/file_information/file_id_full_directory_information.rb +28 -0
  63. data/lib/ruby_smb/fscc/file_information/file_names_information.rb +18 -0
  64. data/lib/ruby_smb/fscc/file_information/file_rename_information.rb +44 -0
  65. data/lib/ruby_smb/generic_packet.rb +40 -18
  66. data/lib/ruby_smb/gss.rb +49 -56
  67. data/lib/ruby_smb/impersonation_levels.rb +7 -2
  68. data/lib/ruby_smb/nbss.rb +16 -0
  69. data/lib/ruby_smb/nbss/negative_session_response.rb +30 -0
  70. data/lib/ruby_smb/nbss/session_header.rb +13 -0
  71. data/lib/ruby_smb/nbss/session_request.rb +13 -0
  72. data/lib/ruby_smb/smb1.rb +20 -17
  73. data/lib/ruby_smb/smb1/bit_field.rb +3 -0
  74. data/lib/ruby_smb/smb1/bit_field/create_options.rb +5 -5
  75. data/lib/ruby_smb/smb1/bit_field/file_status_flags.rb +18 -0
  76. data/lib/ruby_smb/smb1/bit_field/open2_access_mode.rb +11 -11
  77. data/lib/ruby_smb/smb1/bit_field/open2_open_mode.rb +1 -1
  78. data/lib/ruby_smb/smb1/bit_field/optional_support.rb +0 -1
  79. data/lib/ruby_smb/smb1/bit_field/security_flags.rb +15 -0
  80. data/lib/ruby_smb/smb1/bit_field/share_access.rb +2 -3
  81. data/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes.rb +21 -24
  82. data/lib/ruby_smb/smb1/bit_field/smb_file_attributes.rb +1 -1
  83. data/lib/ruby_smb/smb1/commands.rb +5 -0
  84. data/lib/ruby_smb/smb1/create_actions.rb +3 -5
  85. data/lib/ruby_smb/smb1/file.rb +289 -0
  86. data/lib/ruby_smb/smb1/oplock_levels.rb +2 -4
  87. data/lib/ruby_smb/smb1/packet.rb +10 -0
  88. data/lib/ruby_smb/smb1/packet/close_request.rb +31 -0
  89. data/lib/ruby_smb/smb1/packet/close_response.rb +28 -0
  90. data/lib/ruby_smb/smb1/packet/echo_request.rb +5 -7
  91. data/lib/ruby_smb/smb1/packet/echo_response.rb +5 -7
  92. data/lib/ruby_smb/smb1/packet/empty_packet.rb +1 -2
  93. data/lib/ruby_smb/smb1/packet/logoff_request.rb +1 -4
  94. data/lib/ruby_smb/smb1/packet/logoff_response.rb +1 -4
  95. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +22 -0
  96. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +22 -0
  97. data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +62 -0
  98. data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +66 -0
  99. data/lib/ruby_smb/smb1/packet/nt_trans.rb +1 -2
  100. data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +19 -13
  101. data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +8 -10
  102. data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +11 -11
  103. data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +10 -10
  104. data/lib/ruby_smb/smb1/packet/nt_trans/subcommands.rb +8 -1
  105. data/lib/ruby_smb/smb1/packet/read_andx_request.rb +84 -0
  106. data/lib/ruby_smb/smb1/packet/read_andx_response.rb +47 -0
  107. data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -6
  108. data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +1 -4
  109. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -6
  110. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -4
  111. data/lib/ruby_smb/smb1/packet/trans2.rb +8 -2
  112. data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +6 -7
  113. data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +77 -0
  114. data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +87 -0
  115. data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +32 -0
  116. data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info.rb +45 -0
  117. data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +77 -0
  118. data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +86 -0
  119. data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +10 -10
  120. data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +10 -12
  121. data/lib/ruby_smb/smb1/packet/trans2/request.rb +15 -17
  122. data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +8 -10
  123. data/lib/ruby_smb/smb1/packet/trans2/response.rb +11 -13
  124. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +66 -0
  125. data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +57 -0
  126. data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +5 -2
  127. data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -6
  128. data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +5 -7
  129. data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
  130. data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -4
  131. data/lib/ruby_smb/smb1/packet/write_andx_request.rb +68 -0
  132. data/lib/ruby_smb/smb1/packet/write_andx_response.rb +35 -0
  133. data/lib/ruby_smb/smb1/resource_type.rb +18 -0
  134. data/lib/ruby_smb/smb1/tree.rb +188 -5
  135. data/lib/ruby_smb/smb2.rb +16 -11
  136. data/lib/ruby_smb/smb2/bit_field.rb +1 -0
  137. data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +1 -1
  138. data/lib/ruby_smb/smb2/bit_field/session_flags.rb +1 -2
  139. data/lib/ruby_smb/smb2/bit_field/share_flags.rb +4 -6
  140. data/lib/ruby_smb/smb2/create_context.rb +29 -0
  141. data/lib/ruby_smb/smb2/file.rb +251 -0
  142. data/lib/ruby_smb/smb2/info_type.rb +21 -0
  143. data/lib/ruby_smb/smb2/packet.rb +16 -0
  144. data/lib/ruby_smb/smb2/packet/close_request.rb +22 -0
  145. data/lib/ruby_smb/smb2/packet/close_response.rb +29 -0
  146. data/lib/ruby_smb/smb2/packet/create_request.rb +54 -0
  147. data/lib/ruby_smb/smb2/packet/create_response.rb +35 -0
  148. data/lib/ruby_smb/smb2/packet/echo_request.rb +1 -3
  149. data/lib/ruby_smb/smb2/packet/echo_response.rb +1 -3
  150. data/lib/ruby_smb/smb2/packet/error_packet.rb +1 -3
  151. data/lib/ruby_smb/smb2/packet/ioctl_request.rb +54 -0
  152. data/lib/ruby_smb/smb2/packet/ioctl_response.rb +39 -0
  153. data/lib/ruby_smb/smb2/packet/logoff_request.rb +1 -4
  154. data/lib/ruby_smb/smb2/packet/logoff_response.rb +1 -4
  155. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +1 -1
  156. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +1 -1
  157. data/lib/ruby_smb/smb2/packet/query_directory_request.rb +35 -0
  158. data/lib/ruby_smb/smb2/packet/query_directory_response.rb +45 -0
  159. data/lib/ruby_smb/smb2/packet/read_request.rb +30 -0
  160. data/lib/ruby_smb/smb2/packet/read_response.rb +26 -0
  161. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
  162. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +4 -7
  163. data/lib/ruby_smb/smb2/packet/set_info_request.rb +58 -0
  164. data/lib/ruby_smb/smb2/packet/set_info_response.rb +20 -0
  165. data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +3 -4
  166. data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +5 -9
  167. data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +1 -4
  168. data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -4
  169. data/lib/ruby_smb/smb2/packet/write_request.rb +29 -0
  170. data/lib/ruby_smb/smb2/packet/write_response.rb +26 -0
  171. data/lib/ruby_smb/smb2/tree.rb +163 -7
  172. data/lib/ruby_smb/version.rb +1 -1
  173. data/spec/lib/ruby_smb/client_spec.rb +459 -120
  174. data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +14 -0
  175. data/spec/lib/ruby_smb/dcerpc/handle_spec.rb +31 -0
  176. data/spec/lib/ruby_smb/dcerpc/request_spec.rb +21 -0
  177. data/spec/lib/ruby_smb/dcerpc/response_spec.rb +15 -0
  178. data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +13 -0
  179. data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +12 -0
  180. data/spec/lib/ruby_smb/dispatcher/base_spec.rb +26 -0
  181. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +118 -18
  182. data/spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb +0 -3
  183. data/spec/lib/ruby_smb/field/file_time_spec.rb +4 -2
  184. data/spec/lib/ruby_smb/field/security_descriptor.rb +0 -1
  185. data/spec/lib/ruby_smb/field/smb2_fileid_spec.rb +10 -0
  186. data/spec/lib/ruby_smb/field/smb_fea_list_spec.rb +3 -5
  187. data/spec/lib/ruby_smb/field/smb_gea_list_spec.rb +37 -0
  188. data/spec/lib/ruby_smb/field/smb_gea_spec.rb +22 -0
  189. data/spec/lib/ruby_smb/field/stringz16_spec.rb +7 -9
  190. data/spec/lib/ruby_smb/field/utime_spec.rb +4 -2
  191. data/spec/lib/ruby_smb/{field → fscc}/ea_info_array_spec.rb +7 -9
  192. data/spec/lib/ruby_smb/{field → fscc}/file_full_ea_info_spec.rb +2 -3
  193. data/spec/lib/ruby_smb/fscc/file_information/file_both_directory_information_spec.rb +71 -0
  194. data/spec/lib/ruby_smb/fscc/file_information/file_directory_information_spec.rb +68 -0
  195. data/spec/lib/ruby_smb/fscc/file_information/file_disposition_information_spec.rb +26 -0
  196. data/spec/lib/ruby_smb/fscc/file_information/file_full_directory_information_spec.rb +69 -0
  197. data/spec/lib/ruby_smb/fscc/file_information/file_id_both_directory_information_spec.rb +72 -0
  198. data/spec/lib/ruby_smb/fscc/file_information/file_id_full_directory_information_spec.rb +70 -0
  199. data/spec/lib/ruby_smb/fscc/file_information/file_names_information_spec.rb +41 -0
  200. data/spec/lib/ruby_smb/fscc/file_information/file_rename_information_spec.rb +133 -0
  201. data/spec/lib/ruby_smb/fscc/fscc_file_attributes_spec.rb +143 -0
  202. data/spec/lib/ruby_smb/generic_packet_spec.rb +46 -21
  203. data/spec/lib/ruby_smb/nbss/negative_session_response_spec.rb +29 -0
  204. data/spec/lib/ruby_smb/nbss/session_header_spec.rb +30 -0
  205. data/spec/lib/ruby_smb/nbss/session_request_spec.rb +30 -0
  206. data/spec/lib/ruby_smb/smb1/bit_field/create_options_spec.rb +9 -1
  207. data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +0 -2
  208. data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +0 -2
  209. data/spec/lib/ruby_smb/smb1/bit_field/file_status_flags_spec.rb +35 -0
  210. data/spec/lib/ruby_smb/smb1/bit_field/open2_access_mode_spec.rb +1 -3
  211. data/spec/lib/ruby_smb/smb1/bit_field/open2_flags_spec.rb +0 -2
  212. data/spec/lib/ruby_smb/smb1/bit_field/open2_open_mode_spec.rb +0 -1
  213. data/spec/lib/ruby_smb/smb1/bit_field/optional_support_spec.rb +0 -1
  214. data/spec/lib/ruby_smb/smb1/bit_field/security_flags_spec.rb +26 -0
  215. data/spec/lib/ruby_smb/smb1/bit_field/share_access_spec.rb +0 -3
  216. data/spec/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes_spec.rb +20 -39
  217. data/spec/lib/ruby_smb/smb1/bit_field/smb_file_attributes_spec.rb +0 -6
  218. data/spec/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status_spec.rb +0 -2
  219. data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +0 -2
  220. data/spec/lib/ruby_smb/smb1/bit_field/tree_connect_flags_spec.rb +0 -2
  221. data/spec/lib/ruby_smb/smb1/file_spec.rb +469 -0
  222. data/spec/lib/ruby_smb/smb1/packet/close_request_spec.rb +54 -0
  223. data/spec/lib/ruby_smb/smb1/packet/close_response_spec.rb +45 -0
  224. data/spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb +1 -4
  225. data/spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb +1 -4
  226. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +1 -3
  227. data/spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb +1 -4
  228. data/spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb +1 -4
  229. data/spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb +1 -1
  230. data/spec/lib/ruby_smb/smb1/packet/negotiate_response_extended_spec.rb +37 -0
  231. data/spec/lib/ruby_smb/smb1/packet/negotiate_response_spec.rb +37 -0
  232. data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_request_spec.rb +151 -0
  233. data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_response_spec.rb +157 -0
  234. data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_request_spec.rb +13 -6
  235. data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_response_spec.rb +1 -7
  236. data/spec/lib/ruby_smb/smb1/packet/nt_trans/request_spec.rb +1 -6
  237. data/spec/lib/ruby_smb/smb1/packet/nt_trans/response_spec.rb +1 -5
  238. data/spec/lib/ruby_smb/smb1/packet/read_andx_request_spec.rb +149 -0
  239. data/spec/lib/ruby_smb/smb1/packet/read_andx_response_spec.rb +93 -0
  240. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +1 -5
  241. data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +1 -5
  242. data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +3 -8
  243. data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +2 -4
  244. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +180 -0
  245. data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +104 -0
  246. data/spec/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info_spec.rb +128 -0
  247. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +174 -0
  248. data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +102 -0
  249. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_request_spec.rb +1 -6
  250. data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +2 -7
  251. data/spec/lib/ruby_smb/smb1/packet/trans2/request_secondary_spec.rb +1 -5
  252. data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +1 -5
  253. data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +1 -4
  254. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +98 -0
  255. data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +56 -0
  256. data/spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb +1 -5
  257. data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +1 -6
  258. data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_request_spec.rb +1 -4
  259. data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_response_spec.rb +1 -4
  260. data/spec/lib/ruby_smb/smb1/packet/write_andx_request_spec.rb +148 -0
  261. data/spec/lib/ruby_smb/smb1/packet/write_andx_response_spec.rb +54 -0
  262. data/spec/lib/ruby_smb/smb1/tree_spec.rb +409 -7
  263. data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +0 -2
  264. data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +0 -2
  265. data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +1 -1
  266. data/spec/lib/ruby_smb/smb2/bit_field/share_capabilities_spec.rb +0 -1
  267. data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +0 -2
  268. data/spec/lib/ruby_smb/smb2/create_context_spec.rb +42 -0
  269. data/spec/lib/ruby_smb/smb2/file_spec.rb +233 -0
  270. data/spec/lib/ruby_smb/smb2/packet/close_request_spec.rb +40 -0
  271. data/spec/lib/ruby_smb/smb2/packet/close_response_spec.rb +40 -0
  272. data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +101 -0
  273. data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +64 -0
  274. data/spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb +1 -3
  275. data/spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb +1 -3
  276. data/spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb +48 -0
  277. data/spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb +1 -3
  278. data/spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb +1 -3
  279. data/spec/lib/ruby_smb/smb2/packet/query_directory_request_spec.rb +80 -0
  280. data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +64 -0
  281. data/spec/lib/ruby_smb/smb2/packet/read_request_spec.rb +43 -0
  282. data/spec/lib/ruby_smb/smb2/packet/read_response_spec.rb +50 -0
  283. data/spec/lib/ruby_smb/smb2/packet/session_setup_request_spec.rb +3 -4
  284. data/spec/lib/ruby_smb/smb2/packet/session_setup_response_spec.rb +2 -3
  285. data/spec/lib/ruby_smb/smb2/packet/set_info_request_spec.rb +205 -0
  286. data/spec/lib/ruby_smb/smb2/packet/set_info_response_spec.rb +32 -0
  287. data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +3 -5
  288. data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +1 -2
  289. data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_request_spec.rb +1 -3
  290. data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_response_spec.rb +1 -3
  291. data/spec/lib/ruby_smb/smb2/packet/write_request_spec.rb +51 -0
  292. data/spec/lib/ruby_smb/smb2/packet/write_response_spec.rb +38 -0
  293. data/spec/lib/ruby_smb/smb2/tree_spec.rb +191 -5
  294. data/spec/spec_helper.rb +1 -1
  295. metadata +195 -12
  296. metadata.gz.sig +0 -0
  297. data/lib/ruby_smb/smb1/dispositions.rb +0 -36
  298. data/spec/lib/ruby_smb/dispatcher/dispatcher_base_spec.rb +0 -22
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Bind do
4
+
5
+ describe '#initialize' do
6
+
7
+ let(:bind){described_class.new(endpoint: RubySMB::Dcerpc::Srvsvc)}
8
+ let(:abstract_syntax){bind.p_context_elem.p_cont_elem[0].abstract_syntax}
9
+
10
+ it 'should set the abstract syntax to SrvsvcSyntax' do
11
+ expect(abstract_syntax).to eq RubySMB::Dcerpc::Srvsvc::SrvSvcSyntax.new
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Handle do
4
+
5
+ describe 'A dce/rpc handle' do
6
+ let(:output){double('Output')}
7
+ let(:tree){double('Tree')}
8
+ let(:response){double('Response')}
9
+ let(:file){double('File')}
10
+ let(:handle){described_class.new(file)}
11
+ let(:endpoint){ RubySMB::Dcerpc::Srvsvc }
12
+ let(:ioctl_response){ double('IoctlResponse') }
13
+
14
+ it 'should #bind' do
15
+ expect(handle).to receive(:ioctl_request)#.with([response_socket], nil, nil, timeout)
16
+ handle.bind(endpoint: endpoint)
17
+ end
18
+
19
+ it 'should #request' do
20
+ expect(handle).to receive(:ioctl_request)#.with([response_socket], nil, nil, timeout)
21
+ handle.request(opnum: 15, stub: RubySMB::Dcerpc::Srvsvc::NetShareEnumAll, options: {host: '127.0.0.1'})
22
+ end
23
+
24
+ it 'should #handle_msg' do
25
+ expect(ioctl_response).to receive(:buffer).and_return RubySMB::Dcerpc::Response.new.stub
26
+ expect(RubySMB::Dcerpc::PduHeader).to receive(:read).and_return(RubySMB::Dcerpc::PduHeader.new(ptype: 1))
27
+ expect(handle.handle_msg(ioctl_response)).to eq(RubySMB::Dcerpc::Response.new.stub.to_binary_s)
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Request do
4
+
5
+ describe 'when making a NetShareEnumAll dcerpc request' do
6
+ let(:request){
7
+ described_class.new(
8
+ opnum: RubySMB::Dcerpc::Srvsvc::NetShareEnumAll::Opnum,
9
+ stub: RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: '192.161.204.122').to_binary_s
10
+ )
11
+ }
12
+
13
+ it 'should create a Request struct with NetShareEnumAll as stub with size of 106' do
14
+ expect(request.do_num_bytes).to eq 104
15
+ end
16
+
17
+ it 'should set the correct opnum' do
18
+ expect(request.opnum).to eq 0xF
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Response do
4
+
5
+ let(:raw_response){'0500020310000000b801000000000000a00100000000000001000000010000000000020006000000040002000600000008000200000000800c00020010000200000000001400020018000200000000801c00020020000200000000002400020028000200030000802c000200300002000000000034000200070000000000000007000000410044004d0049004e002400000000000d000000000000000d000000520065006d006f00740065002000410064006d0069006e0000000000020000000000000002000000430000000100000000000000010000000000000003000000000000000300000043002400000000000e000000000000000e000000440065006600610075006c007400200073006800610072006500000007000000000000000700000064006f00670065003600340000000000010000000000000001000000000000000500000000000000050000004900500043002400000000000b000000000000000b000000520065006d006f00740065002000490050004300000000000600000000000000060000005500730065007200730000000100000000000000010000000000000006000000380002000000000000000000'.strip.gsub(/([A-Fa-f0-9]{1,2})\s*?/) { $1.hex.chr }}
6
+
7
+ describe '#read' do
8
+
9
+ let(:response){described_class.read(raw_response)}
10
+
11
+ it 'should use the alloc_hint to determine stub length' do
12
+ expect(response.stub.do_num_bytes).to eq response.alloc_hint
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Srvsvc do
4
+
5
+ describe 'when making a NetShareEnumAll struct' do
6
+ let(:stub){ RubySMB::Dcerpc::Srvsvc::NetShareEnumAll.new(host: '192.161.204.122') }
7
+
8
+ it 'crafts an 8 octet aligned stub' do
9
+ expect(stub.do_num_bytes).to eq 80
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dcerpc::Uuid do
4
+ let(:uuid_string){'8a885d04-1ceb-11c9-9fe8-08002b104860'}
5
+ let(:uuid){RubySMB::Dcerpc::Uuid.new(initial_value: uuid_string)}
6
+
7
+ describe '#initialize' do
8
+ it 'should create a 16 byte struct' do
9
+ expect(uuid.do_num_bytes).to be 16
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Dispatcher::Base do
4
+ subject(:dispatcher) { described_class.new }
5
+ let(:session_header) { RubySMB::Nbss::SessionHeader.new }
6
+ let(:packet) { RubySMB::SMB1::Packet::NegotiateRequest.new }
7
+
8
+ describe '#nbss' do
9
+ it 'creates a SessionHeader packet' do
10
+ expect(RubySMB::Nbss::SessionHeader).to receive(:new).and_return(session_header)
11
+ dispatcher.nbss(packet)
12
+ end
13
+
14
+ it 'returns the size of the packet to the packet in 4 bytes' do
15
+ expect(dispatcher.nbss(packet)).to eq "\x00\x00\x00\x23"
16
+ end
17
+ end
18
+
19
+ it 'raises NotImplementedError on #send_packet' do
20
+ expect { dispatcher.send_packet('foo') }.to raise_error(NotImplementedError)
21
+ end
22
+
23
+ it 'raises NotImplementedError on #recv_packet' do
24
+ expect { dispatcher.recv_packet }.to raise_error(NotImplementedError)
25
+ end
26
+ end
@@ -1,8 +1,6 @@
1
1
  RSpec.describe RubySMB::Dispatcher::Socket do
2
2
  class FakeSocket < StringIO
3
- def setsockopt(*args)
4
-
5
- end
3
+ def setsockopt(*args); end
6
4
  end
7
5
 
8
6
  let(:fake_tcp_socket) {
@@ -16,7 +14,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
16
14
 
17
15
  # Don't try to actually select on our StringIO fake socket
18
16
  before(:each) do
19
- allow(IO).to receive(:select).and_return(nil)
17
+ allow(IO).to receive(:select).and_return([])
20
18
  end
21
19
 
22
20
  it 'should attempt to set KEEPALIVE on the socket' do
@@ -24,6 +22,15 @@ RSpec.describe RubySMB::Dispatcher::Socket do
24
22
  described_class.new(fake_tcp_socket)
25
23
  end
26
24
 
25
+ it 'sets the default read_timeout value to READ_TIMEOUT' do
26
+ expect(described_class.new(fake_tcp_socket).read_timeout).to eq(described_class::READ_TIMEOUT)
27
+ end
28
+
29
+ it 'accepts a read_timeout value as arguments' do
30
+ read_timeout = 10
31
+ expect(described_class.new(fake_tcp_socket, read_timeout: read_timeout).read_timeout).to eq(read_timeout)
32
+ end
33
+
27
34
  describe '#connect' do
28
35
  it 'should support setting a custom socket object' do
29
36
  socket = described_class.connect('172.16.22.165', socket: fake_tcp_socket)
@@ -39,35 +46,128 @@ RSpec.describe RubySMB::Dispatcher::Socket do
39
46
  end
40
47
 
41
48
  describe '#recv_packet' do
42
- let(:blank_socket) { StringIO.new('') }
49
+ let(:blank_socket) { StringIO.new('') }
43
50
  let(:response_socket) { StringIO.new(response_packet) }
51
+ let(:session_header) { RubySMB::Nbss::SessionHeader.new }
52
+
53
+ context 'when reading from the socket results in a nil value' do
54
+ it 'should raise Error::NetBiosSessionService' do
55
+ smb_socket.tcp_socket = blank_socket
56
+ expect { smb_socket.recv_packet }.to raise_error(::RubySMB::Error::NetBiosSessionService)
57
+ end
58
+ end
44
59
 
45
- describe 'when reading from the socket results in a nil value' do
60
+ context 'when reading from the socket results in an empty value' do
46
61
  it 'should raise Error::NetBiosSessionService' do
47
62
  smb_socket.tcp_socket = blank_socket
63
+ allow(blank_socket).to receive(:read).and_return('')
48
64
  expect { smb_socket.recv_packet }.to raise_error(::RubySMB::Error::NetBiosSessionService)
49
65
  end
50
66
  end
51
67
 
52
- describe 'when reading an SMB Response packet' do
53
- it 'reads a number of bytes defined in the nbss header' do
68
+ context 'when a socket error occurs' do
69
+ it 'raises a CommunicationError exception' do
70
+ expect(fake_tcp_socket).to receive(:read).and_raise(Errno::ECONNRESET)
71
+ expect { smb_socket.recv_packet }.to raise_error(RubySMB::Error::CommunicationError)
72
+ end
73
+ end
74
+
75
+ context 'when the read_timeout expires' do
76
+ it 'raises a CommunicationError exception' do
77
+ allow(IO).to receive(:select).and_return(nil)
78
+ expect { smb_socket.recv_packet }.to raise_error(RubySMB::Error::CommunicationError)
79
+ end
80
+ end
81
+
82
+ context 'when reading an SMB Response packet' do
83
+ before :example do
54
84
  smb_socket.tcp_socket = response_socket
55
- expect(response_socket).to receive(:read).with(4).and_call_original
56
- expect(response_socket).to receive(:read).with(negotiate_response.do_num_bytes).and_call_original
85
+ end
86
+
87
+ it 'reads the nbss header using Nbss::SessionHeader structure' do
88
+ expect(RubySMB::Nbss::SessionHeader).to receive(:read).with(response_socket).and_return(session_header)
57
89
  smb_socket.recv_packet
58
90
  end
59
- end
60
91
 
61
- it 'raises a CommunicationError if it encounters a socket error' do
62
- expect(fake_tcp_socket).to receive(:read).and_raise(Errno::ECONNRESET)
63
- expect{ smb_socket.recv_packet }.to raise_error(RubySMB::Error::CommunicationError)
92
+ it 'uses the default read_timeout with IO#select when it has not been specifically defined' do
93
+ expect(IO).to receive(:select).with([response_socket], nil, nil, described_class::READ_TIMEOUT).and_return([]).twice
94
+ smb_socket.recv_packet
95
+ end
96
+
97
+ it 'uses the defined read_timeout with IO#select' do
98
+ timeout = 10
99
+ smb_socket.read_timeout = timeout
100
+ expect(IO).to receive(:select).with([response_socket], nil, nil, timeout).and_return([]).twice
101
+ smb_socket.recv_packet
102
+ end
103
+
104
+ it 'reads the number of bytes specified in the nbss header' do
105
+ packet_length = 10
106
+ session_header.packet_length = packet_length
107
+ allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
108
+ expect(response_socket).to receive(:read).with(packet_length).and_return('A' * packet_length)
109
+ smb_socket.recv_packet
110
+ end
111
+
112
+ context 'when the socket does not return everything the first time' do
113
+ it 'calls #read several times until everything is returned' do
114
+ packet_length = 67
115
+ returned_length = 10
116
+ session_header.packet_length = packet_length
117
+ allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
118
+
119
+ loop do
120
+ expect(response_socket).to receive(:read).with(packet_length).and_return('A' * returned_length).once
121
+ packet_length -= returned_length
122
+ break if packet_length <= 0
123
+ end
124
+ smb_socket.recv_packet
125
+ end
126
+ end
127
+
128
+ context 'when the full_response argument is true' do
129
+ it 'returns the full packet including the nbss header' do
130
+ expect(smb_socket.recv_packet(full_response: true)).to eq(response_packet)
131
+ end
132
+
133
+ context 'when the SMB packet is empty' do
134
+ it 'returns the nbss header only' do
135
+ session_header.packet_length = 0
136
+ allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
137
+ expect(smb_socket.recv_packet(full_response: true)).to eq(session_header.to_binary_s)
138
+ end
139
+ end
140
+ end
141
+
142
+ context 'when the full_response argument is false' do
143
+ it 'returns the SMB packet without the nbss header' do
144
+ expect(smb_socket.recv_packet(full_response: false)).to eq(negotiate_response.to_binary_s)
145
+ end
146
+
147
+ context 'when the SMB packet is empty' do
148
+ it 'returns an empty string' do
149
+ session_header.packet_length = 0
150
+ allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
151
+ expect(smb_socket.recv_packet(full_response: false)).to eq('')
152
+ end
153
+ end
154
+ end
64
155
  end
65
156
  end
66
157
 
67
158
  describe '#send_packet' do
68
- it 'calls nbss to create the nbss header for the packet' do
69
- expect(smb_socket).to receive(:nbss).with(negotiate_response).and_return(nbss)
70
- smb_socket.send_packet(negotiate_response)
159
+ context 'when nbss_header argument is true' do
160
+ it 'calls #nbss to create the nbss header for the packet' do
161
+ expect(smb_socket).to receive(:nbss).with(negotiate_response).and_return(nbss)
162
+ smb_socket.send_packet(negotiate_response, nbss_header: true)
163
+ end
164
+ end
165
+
166
+ context 'when nbss_header argument is false' do
167
+ it 'does not call #nbss' do
168
+ expect(smb_socket).to_not receive(:nbss)
169
+ smb_socket.send_packet(negotiate_response, nbss_header: false)
170
+ end
71
171
  end
72
172
 
73
173
  it 'writes the packet to the socket' do
@@ -77,7 +177,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
77
177
 
78
178
  it 'raises a CommunicationError if it encounters a socket error' do
79
179
  expect(fake_tcp_socket).to receive(:write).and_raise(Errno::ECONNRESET)
80
- expect{ smb_socket.send_packet(negotiate_response) }.to raise_error(RubySMB::Error::CommunicationError)
180
+ expect { smb_socket.send_packet(negotiate_response) }.to raise_error(RubySMB::Error::CommunicationError)
81
181
  end
82
182
  end
83
183
  end
@@ -3,14 +3,11 @@ RSpec.describe RubySMB::Field::ExtendedAttributeFlag do
3
3
 
4
4
  it { is_expected.to respond_to :file_need_ea }
5
5
 
6
-
7
6
  describe 'file_need_ea' do
8
7
  it 'should be a 1-bit field per the SMB spec' do
9
8
  expect(flag.file_need_ea).to be_a BinData::Bit1
10
9
  end
11
10
 
12
-
13
11
  it_behaves_like 'bit field with one flag set', :file_need_ea, 'C', 0x80
14
12
  end
15
-
16
13
  end
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  RSpec.describe RubySMB::Field::FileTime do
2
4
  subject(:file_time) { described_class.read(binary_filetime) }
3
5
 
@@ -42,13 +44,13 @@ RSpec.describe RubySMB::Field::FileTime do
42
44
  it 'will take a Time object correctly but lose Nanoseconds' do
43
45
  empty_filetime.set time_filetime
44
46
  val = empty_filetime.get
45
- expect(val / 10_000_000).to eq (int_filetime / 10_000_000)
47
+ expect(val / 10_000_000).to eq(int_filetime / 10_000_000)
46
48
  end
47
49
 
48
50
  it 'will take a DateTime object correctly but lose Nanoseconds' do
49
51
  empty_filetime.set datetime_filetime
50
52
  val = empty_filetime.get
51
- expect(val / 10_000_000).to eq (int_filetime / 10_000_000)
53
+ expect(val / 10_000_000).to eq(int_filetime / 10_000_000)
52
54
  end
53
55
 
54
56
  it 'will accept a raw integer value and set it' do
@@ -191,4 +191,3 @@ RSpec.describe RubySMB::Field::SecurityDescriptor do
191
191
  end
192
192
  end
193
193
  end
194
-
@@ -0,0 +1,10 @@
1
+ RSpec.describe RubySMB::Field::Smb2Fileid do
2
+ subject(:fea) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :persistent }
5
+ it { is_expected.to respond_to :volatile }
6
+
7
+ it 'is little endian' do
8
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
9
+ end
10
+ end
@@ -1,23 +1,21 @@
1
1
  RSpec.describe RubySMB::Field::SmbFeaList do
2
2
  subject(:list) { described_class.new }
3
- let(:fea1) {
3
+ let(:fea1) {
4
4
  fea = RubySMB::Field::SmbFea.new
5
5
  fea.attribute_name = 'foo'
6
6
  fea.attribute_value = 'bar'
7
7
  fea
8
8
  }
9
- let(:fea2) {
9
+ let(:fea2) {
10
10
  fea = RubySMB::Field::SmbFea.new
11
11
  fea.attribute_name = 'hello world'
12
12
  fea.attribute_value = 'this is a test'
13
13
  fea
14
14
  }
15
15
 
16
-
17
16
  it { is_expected.to respond_to :size_of_list }
18
17
  it { is_expected.to respond_to :fea_list }
19
18
 
20
-
21
19
  it 'is little endian' do
22
20
  expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
23
21
  end
@@ -32,7 +30,7 @@ RSpec.describe RubySMB::Field::SmbFeaList do
32
30
  list.fea_list << fea1
33
31
  expect(list.size_of_list).to eq fea1.do_num_bytes
34
32
  list.fea_list << fea2
35
- expect(list.size_of_list).to eq (fea1.do_num_bytes + fea2.do_num_bytes )
33
+ expect(list.size_of_list).to eq(fea1.do_num_bytes + fea2.do_num_bytes)
36
34
  end
37
35
  end
38
36
  end
@@ -0,0 +1,37 @@
1
+ RSpec.describe RubySMB::Field::SmbGeaList do
2
+ subject(:list) { described_class.new }
3
+ let(:gea1) {
4
+ fea = RubySMB::Field::SmbGea.new
5
+ fea.attribute_name = 'foo'
6
+ fea
7
+ }
8
+ let(:gea2) {
9
+ fea = RubySMB::Field::SmbGea.new
10
+ fea.attribute_name = 'hello world'
11
+ fea
12
+ }
13
+
14
+ it { is_expected.to respond_to :size_of_list }
15
+ it { is_expected.to respond_to :gea_list }
16
+
17
+ it 'is little endian' do
18
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
19
+ end
20
+
21
+ describe '#size_of_list' do
22
+ it 'shows the size, in bytes, of the fea_list' do
23
+ list.gea_list << gea1
24
+ total_size = list.size_of_list.do_num_bytes + gea1.do_num_bytes
25
+ expect(list.size_of_list).to eq total_size
26
+ end
27
+
28
+ it 'changes dynamically as new GEAs are added' do
29
+ list.gea_list << gea1
30
+ total_size = list.size_of_list.do_num_bytes + gea1.do_num_bytes
31
+ expect(list.size_of_list).to eq total_size
32
+ list.gea_list << gea2
33
+ total_size += gea2.do_num_bytes
34
+ expect(list.size_of_list).to eq total_size
35
+ end
36
+ end
37
+ end