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
@@ -1,12 +1,11 @@
1
1
  module RubySMB
2
2
  module SMB1
3
3
  module Packet
4
-
5
4
  # This class represents an SMB1 TreeDisonnect Response Packet as defined in
6
5
  # [2.2.4.51.2 Response](https://msdn.microsoft.com/en-us/library/ee441823.aspx)
7
6
  class TreeDisconnectResponse < RubySMB::GenericPacket
8
-
9
7
  # The Parameter Block for this packet is empty save the Word Count
8
+ # The {RubySMB::SMB1::ParameterBlock} specific to this packet type.
10
9
  class ParameterBlock < RubySMB::SMB1::ParameterBlock
11
10
  end
12
11
 
@@ -23,8 +22,7 @@ module RubySMB
23
22
  smb_header.command = RubySMB::SMB1::Commands::SMB_COM_TREE_DISCONNECT
24
23
  smb_header.flags.reply = 1
25
24
  end
26
-
27
25
  end
28
26
  end
29
27
  end
30
- end
28
+ end
@@ -0,0 +1,68 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module Packet
4
+ # A SMB1 SMB_COM_WRITE_ANDX Request Packet as defined in
5
+ # [2.2.4.43.1 Request](https://msdn.microsoft.com/en-us/library/ee441954.aspx)
6
+ # [2.2.4.3.1 Client Request Extensions](https://msdn.microsoft.com/en-us/library/ff469893.aspx)
7
+ class WriteAndxRequest < RubySMB::GenericPacket
8
+ # A SMB1 Parameter Block as defined by the {WriteAndxRequest}
9
+ class ParameterBlock < RubySMB::SMB1::ParameterBlock
10
+ endian :little
11
+
12
+ and_x_block :andx_block
13
+ uint16 :fid, label: 'FID'
14
+ uint32 :offset, label: 'Offset'
15
+ uint32 :timeout, label: 'Timeout'
16
+
17
+ struct :write_mode, label: 'Write Mode' do
18
+ bit4 :reserved, label: 'Reserved Space'
19
+ bit1 :msg_start, label: 'Message Start'
20
+ bit1 :raw_mode, label: 'Raw Mode'
21
+ bit1 :read_bytes_available, label: 'Read Bytes Available'
22
+ bit1 :writethrough_mode, label: 'Writethrough Mode'
23
+ # byte boundary
24
+ bit8 :reserved2, label: 'Reserved Space'
25
+ end
26
+
27
+ uint16 :remaining, label: 'Remaining'
28
+ uint16 :data_length_high, label: 'Data Length High'
29
+ uint16 :data_length, label: 'Data Length(bytes)', value: -> { parent.data_block.data.length }
30
+ uint16 :data_offset, label: 'Data Offset', value: -> { parent.data_block.data.abs_offset }
31
+ uint32 :offset_high, label: 'Offset High', onlyif: -> { word_count == 0x0E }
32
+
33
+ # Bypass the word count calculation to use 32-bit offset by default.
34
+ # As a result, the optional offset_high field won't be defined until
35
+ # #set_64_bit_offset(true) is explicitly called.
36
+ def calculate_word_count
37
+ 0x0C
38
+ end
39
+ private :calculate_word_count
40
+ end
41
+
42
+ # Represents the specific layout of the DataBlock for a {WriteAndxRequest} Packet.
43
+ class DataBlock < RubySMB::SMB1::DataBlock
44
+ uint8 :pad, label: 'Pad'
45
+ string :data, label: 'Data'
46
+ end
47
+
48
+ smb_header :smb_header
49
+ parameter_block :parameter_block
50
+ data_block :data_block
51
+
52
+ def initialize_instance
53
+ super
54
+ smb_header.command = RubySMB::SMB1::Commands::SMB_COM_WRITE_ANDX
55
+ end
56
+
57
+ # Specifies whether the offset is a 32-bit (default) or 64-bit value. When `is_64_bit`
58
+ # is true, a 64-bit offset will be used and the OffsetHigh field will be added to the structure.
59
+ #
60
+ # @param is_64_bit [TrueClass, FalseClass] use a 64-bit offset if set to true, 32-bit otherwise
61
+ def set_64_bit_offset(is_64_bit)
62
+ raise ArgumentError.new, 'The value can only be true or false' unless [true, false].include?(is_64_bit)
63
+ parameter_block.word_count = is_64_bit ? 0x0E : 0x0C
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ module RubySMB
2
+ module SMB1
3
+ module Packet
4
+ # A SMB1 SMB_COM_WRITE_ANDX Response Packet as defined in
5
+ # [2.2.4.43.2 Response](https://msdn.microsoft.com/en-us/library/ee441673.aspx)
6
+ # [2.2.4.3.2 Server Response Extensions](https://msdn.microsoft.com/en-us/library/ff469858.aspx)
7
+ class WriteAndxResponse < RubySMB::GenericPacket
8
+ # A SMB1 Parameter Block as defined by the {WriteAndxResponse}
9
+ class ParameterBlock < RubySMB::SMB1::ParameterBlock
10
+ endian :little
11
+
12
+ and_x_block :andx_block
13
+ uint16 :count_low, label: 'Count Low'
14
+ uint16 :available, label: 'Available'
15
+ uint16 :count_high, label: 'Count High'
16
+ uint16 :reserved, label: 'Reserved'
17
+ end
18
+
19
+ # Represents the specific layout of the DataBlock for a {WriteAndxResponse} Packet.
20
+ class DataBlock < RubySMB::SMB1::DataBlock
21
+ end
22
+
23
+ smb_header :smb_header
24
+ parameter_block :parameter_block
25
+ data_block :data_block
26
+
27
+ def initialize_instance
28
+ super
29
+ smb_header.command = RubySMB::SMB1::Commands::SMB_COM_WRITE_ANDX
30
+ smb_header.flags.reply = 1
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ module RubySMB
2
+ module SMB1
3
+ # This module holds the ResourceType used in SMB_COM_OPEN_ANDX and SMB_COM_NT_CREATE_ANDX
4
+ # responses. The definitions for these values can be found at
5
+ # [2.2.4.64.2 Response](https://msdn.microsoft.com/en-us/library/ee441612.aspx)
6
+ # [2.2.4.9.2 Server Response Extensions](https://msdn.microsoft.com/en-us/library/cc246334.aspx)
7
+ module ResourceType
8
+ # File or directory
9
+ DISK = 0x0000
10
+ # Byte mode named pipe
11
+ BYTE_MODE_PIPE = 0x0001
12
+ # Message mode named pipe
13
+ MESSAGE_MODE_PIPE = 0x0002
14
+ # Printer device
15
+ PRINTER = 0x0003
16
+ end
17
+ end
18
+ end
@@ -1,10 +1,8 @@
1
1
  module RubySMB
2
2
  module SMB1
3
-
4
3
  # An SMB1 connected remote Tree, as returned by a
5
4
  # [RubySMB::SMB1::Packet::TreeConnectRequest]
6
5
  class Tree
7
-
8
6
  # The client this Tree is connected through
9
7
  # @!attribute [rw] client
10
8
  # @return [RubySMB::Client]
@@ -43,13 +41,198 @@ module RubySMB
43
41
  # @return [WindowsError::ErrorCode] the NTStatus sent back by the server.
44
42
  def disconnect!
45
43
  request = RubySMB::SMB1::Packet::TreeDisconnectRequest.new
46
- request.smb_header.tid = self.id
47
- raw_response = self.client.send_recv(request)
44
+ request = set_header_fields(request)
45
+ raw_response = client.send_recv(request)
48
46
  response = RubySMB::SMB1::Packet::TreeDisconnectResponse.read(raw_response)
49
47
  response.status_code
50
48
  end
51
49
 
50
+ # Open a file on the remote share.
51
+ #
52
+ # @example
53
+ # tree = client.tree_connect("\\\\192.168.99.134\\Share")
54
+ # tree.open_file(filename: "myfile")
55
+ #
56
+ # @param filename [String] name of the file to be opened
57
+ # @param flags [BinData::Struct, Hash] flags to setup the request (see {RubySMB::SMB1::Packet::NtCreateAndxRequest})
58
+ # @param options [RubySMB::SMB1::BitField::CreateOptions, Hash] flags that defines how the file should be created
59
+ # @param disposition [Integer] 32-bit field that defines how an already-existing file or a new file needs to be handled (constants are defined in {RubySMB::Dispositions})
60
+ # @param impersonation [Integer] 32-bit field that defines the impersonation level (constants are defined in {RubySMB::ImpersonationLevels})
61
+ # @param read [TrueClass, FalseClass] request a read access
62
+ # @param write [TrueClass, FalseClass] request a write access
63
+ # @param delete [TrueClass, FalseClass] request a delete access
64
+ # @return [RubySMB::SMB1::File] handle to the created file
65
+ # @raise [RubySMB::Error::InvalidPacket] if the response command is not SMB_COM_NT_CREATE_ANDX
66
+ # @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
67
+ def open_file(filename:, flags: nil, options: nil, disposition: RubySMB::Dispositions::FILE_OPEN,
68
+ impersonation: RubySMB::ImpersonationLevels::SEC_IMPERSONATE, read: true, write: false, delete: false)
69
+ nt_create_andx_request = RubySMB::SMB1::Packet::NtCreateAndxRequest.new
70
+ nt_create_andx_request = set_header_fields(nt_create_andx_request)
71
+
72
+ nt_create_andx_request.parameter_block.ext_file_attributes.normal = 1
73
+
74
+ if flags
75
+ nt_create_andx_request.parameter_block.flags = flags
76
+ else
77
+ nt_create_andx_request.parameter_block.flags.request_extended_response = 1
78
+ end
79
+
80
+ if options
81
+ nt_create_andx_request.parameter_block.create_options = options
82
+ else
83
+ nt_create_andx_request.parameter_block.create_options.directory_file = 0
84
+ nt_create_andx_request.parameter_block.create_options.non_directory_file = 1
85
+ end
86
+
87
+ if read
88
+ nt_create_andx_request.parameter_block.share_access.share_read = 1
89
+ nt_create_andx_request.parameter_block.desired_access.read_data = 1
90
+ nt_create_andx_request.parameter_block.desired_access.read_ea = 1
91
+ nt_create_andx_request.parameter_block.desired_access.read_attr = 1
92
+ nt_create_andx_request.parameter_block.desired_access.read_control = 1
93
+ end
94
+
95
+ if write
96
+ nt_create_andx_request.parameter_block.share_access.share_write = 1
97
+ nt_create_andx_request.parameter_block.desired_access.write_data = 1
98
+ nt_create_andx_request.parameter_block.desired_access.append_data = 1
99
+ nt_create_andx_request.parameter_block.desired_access.write_ea = 1
100
+ nt_create_andx_request.parameter_block.desired_access.write_attr = 1
101
+ end
102
+
103
+ if delete
104
+ nt_create_andx_request.parameter_block.share_access.share_delete = 1
105
+ nt_create_andx_request.parameter_block.desired_access.delete_access = 1
106
+ end
107
+
108
+ nt_create_andx_request.parameter_block.impersonation_level = impersonation
109
+ nt_create_andx_request.parameter_block.create_disposition = disposition
110
+
111
+ unicode_enabled = nt_create_andx_request.smb_header.flags2.unicode == 1
112
+ nt_create_andx_request.data_block.file_name = add_null_termination(str: filename, unicode: unicode_enabled)
113
+
114
+ raw_response = @client.send_recv(nt_create_andx_request)
115
+ response = RubySMB::SMB1::Packet::NtCreateAndxResponse.read(raw_response)
116
+ unless response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_NT_CREATE_ANDX
117
+ raise RubySMB::Error::InvalidPacket, 'Not a NtCreateAndxResponse packet'
118
+ end
119
+ unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
120
+ raise RubySMB::Error::UnexpectedStatusCode, response.status_code.name
121
+ end
122
+
123
+ RubySMB::SMB1::File.new(name: filename, tree: self, response: response)
124
+ end
125
+
126
+ # List `directory` on the remote share.
127
+ #
128
+ # @example
129
+ # tree = client.tree_connect("\\\\192.168.99.134\\Share")
130
+ # tree.list(directory: "path\\to\\directory")
131
+ #
132
+ # @param directory [String] path to the directory to be listed
133
+ # @param pattern [String] search pattern
134
+ # @param type [Class] file information class
135
+ # @return [Array] array of directory structures
136
+ def list(directory: '\\', pattern: '*', unicode: true,
137
+ type: RubySMB::SMB1::Packet::Trans2::FindInformationLevel::FindFileFullDirectoryInfo)
138
+ find_first_request = RubySMB::SMB1::Packet::Trans2::FindFirst2Request.new
139
+ find_first_request = set_header_fields(find_first_request)
140
+ find_first_request.smb_header.flags2.unicode = 1 if unicode
141
+
142
+ search_path = directory.dup
143
+ search_path << '\\' unless search_path.end_with?('\\')
144
+ search_path << pattern
145
+ search_path = '\\' + search_path unless search_path.start_with?('\\')
146
+
147
+ # Set the search parameters
148
+ t2_params = find_first_request.data_block.trans2_parameters
149
+ t2_params.search_attributes.hidden = 1
150
+ t2_params.search_attributes.system = 1
151
+ t2_params.search_attributes.directory = 1
152
+ t2_params.flags.close_eos = 1
153
+ t2_params.flags.resume_keys = 0
154
+ t2_params.information_level = type::CLASS_LEVEL
155
+ t2_params.filename = search_path
156
+ t2_params.search_count = 10
157
+
158
+ find_first_request = set_find_params(find_first_request)
159
+
160
+ raw_response = client.send_recv(find_first_request)
161
+ response = RubySMB::SMB1::Packet::Trans2::FindFirst2Response.read(raw_response)
162
+
163
+ results = response.results(type, unicode: unicode)
164
+
165
+ eos = response.data_block.trans2_parameters.eos
166
+ sid = response.data_block.trans2_parameters.sid
167
+ last = results.last.file_name
168
+
169
+ while eos.zero?
170
+ find_next_request = RubySMB::SMB1::Packet::Trans2::FindNext2Request.new
171
+ find_next_request = set_header_fields(find_next_request)
172
+ find_next_request.smb_header.flags2.unicode = 1 if unicode
173
+
174
+ t2_params = find_next_request.data_block.trans2_parameters
175
+ t2_params.sid = sid
176
+ t2_params.flags.close_eos = 1
177
+ t2_params.flags.resume_keys = 0
178
+ t2_params.information_level = type::CLASS_LEVEL
179
+ t2_params.filename = last
180
+ t2_params.search_count = 10
181
+
182
+ find_next_request = set_find_params(find_next_request)
183
+
184
+ raw_response = client.send_recv(find_next_request)
185
+ response = RubySMB::SMB1::Packet::Trans2::FindNext2Response.read(raw_response)
186
+
187
+ results += response.results(type, unicode: unicode)
188
+
189
+ eos = response.data_block.trans2_parameters.eos
190
+ last = results.last.file_name
191
+ end
192
+
193
+ results
194
+ end
195
+
196
+ # Sets a few preset header fields that will always be set the same
197
+ # way for Tree operations. This is, the TreeID and Extended Attributes.
198
+ #
199
+ # @param [RubySMB::SMB::Packet] the request packet to modify
200
+ # @return [RubySMB::SMB::Packet] the modified packet.
201
+ def set_header_fields(request)
202
+ request.smb_header.tid = @id
203
+ request.smb_header.flags2.eas = 1
204
+ request
205
+ end
206
+
207
+ private
208
+
209
+ # Sets ParameterBlock options for FIND_FIRST2 and
210
+ # FIND_NEXT2 requests. In particular we need to do this
211
+ # to tell the server to ignore the Trans2DataBlock as we are
212
+ # not sending any GEA lists in this instance.
213
+ def set_find_params(request)
214
+ request.parameter_block.data_count = 0
215
+ request.parameter_block.data_offset = 0
216
+ request.parameter_block.total_parameter_count = request.parameter_block.parameter_count
217
+ request.parameter_block.max_parameter_count = request.parameter_block.parameter_count
218
+ request.parameter_block.max_data_count = 16_384
219
+ request
220
+ end
221
+
222
+ # Add null termination to `str` in case it is not already null-terminated.
223
+ #
224
+ # @str [String] the string to be null-terminated
225
+ # @unicode [TrueClass, FalseClass] True if the null-termination should be Unicode encoded
226
+ # @return [String] the null-terminated string
227
+ def add_null_termination(str:, unicode: false)
228
+ null_termination = unicode ? "\x00".encode('UTF-16LE') : "\x00"
229
+ if str.end_with?(null_termination)
230
+ return str
231
+ else
232
+ return str + null_termination
233
+ end
234
+ end
52
235
 
53
236
  end
54
237
  end
55
- end
238
+ end
data/lib/ruby_smb/smb2.rb CHANGED
@@ -1,13 +1,18 @@
1
- # A packet parsing and manipulation library for the SMB2 protocol
2
- #
3
- # [[MS-SMB2] Server Mesage Block (SMB) Protocol Versions 2 and 3](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
4
- module RubySMB::SMB2
5
- # Protocol ID value. Translates to \xFESMB
6
- SMB2_PROTOCOL_ID = 0xFE534D42
1
+ module RubySMB
2
+ # A packet parsing and manipulation library for the SMB2 protocol
3
+ #
4
+ # [[MS-SMB2] Server Mesage Block (SMB) Protocol Versions 2 and 3](https://msdn.microsoft.com/en-us/library/cc246482.aspx)
5
+ module SMB2
6
+ # Protocol ID value. Translates to \xFESMB
7
+ SMB2_PROTOCOL_ID = 0xFE534D42
7
8
 
8
- require 'ruby_smb/smb2/commands'
9
- require 'ruby_smb/smb2/bit_field'
10
- require 'ruby_smb/smb2/smb2_header'
11
- require 'ruby_smb/smb2/packet'
12
- require 'ruby_smb/smb2/tree'
9
+ require 'ruby_smb/smb2/info_type'
10
+ require 'ruby_smb/smb2/commands'
11
+ require 'ruby_smb/smb2/create_context'
12
+ require 'ruby_smb/smb2/bit_field'
13
+ require 'ruby_smb/smb2/smb2_header'
14
+ require 'ruby_smb/smb2/packet'
15
+ require 'ruby_smb/smb2/tree'
16
+ require 'ruby_smb/smb2/file'
17
+ end
13
18
  end
@@ -1,5 +1,6 @@
1
1
  module RubySMB
2
2
  module SMB2
3
+ # Namespace for BitMask style field definitions
3
4
  module BitField
4
5
  require 'ruby_smb/smb2/bit_field/smb2_header_flags'
5
6
  require 'ruby_smb/smb2/bit_field/smb2_security_mode'
@@ -7,7 +7,7 @@ module RubySMB
7
7
  endian :little
8
8
  bit1 :read_attr, label: 'Read Attributes'
9
9
  bit1 :delete_child, label: 'Delete Child'
10
- bit1 :execute, label: 'Traverse'
10
+ bit1 :execute, label: 'Execute'
11
11
  bit1 :write_ea, label: 'Write Extended Attributes'
12
12
  bit1 :read_ea, label: 'Read Extended Attributes'
13
13
  bit1 :append_data, label: 'Append Data'
@@ -9,8 +9,7 @@ module RubySMB
9
9
  bit1 :guest, label: 'Is Guest?', initial_value: 0
10
10
  resume_byte_alignment
11
11
  # byte border
12
- uint8 :reserved1, label: 'Reserved', initial_value: 0
13
-
12
+ uint8 :reserved1, label: 'Reserved', initial_value: 0
14
13
  end
15
14
  end
16
15
  end
@@ -1,7 +1,6 @@
1
1
  module RubySMB
2
2
  module SMB2
3
3
  module BitField
4
-
5
4
  # A Share Flags BitField Mask as defined in
6
5
  # [2.2.10 SMB2 TREE_CONNECT Response](https://msdn.microsoft.com/en-us/library/cc246499.aspx)
7
6
  class ShareFlags < BinData::Record
@@ -26,11 +25,11 @@ module RubySMB
26
25
  bit8 :reserved4, label: 'Reserved Space'
27
26
 
28
27
  def caching_type
29
- if self.vdo_caching == 1 && self.auto_caching == 0
28
+ if vdo_caching == 1 && auto_caching.zero?
30
29
  :vdo
31
- elsif self.vdo_caching == 0 && self.auto_caching == 1
30
+ elsif vdo_caching.zero? && auto_caching == 1
32
31
  :auto
33
- elsif self.vdo_caching == 1 && self.auto_caching == 1
32
+ elsif vdo_caching == 1 && auto_caching == 1
34
33
  :no_caching
35
34
  else
36
35
  :manual
@@ -68,8 +67,7 @@ module RubySMB
68
67
  self.vdo_caching = 1
69
68
  self.auto_caching = 1
70
69
  end
71
-
72
70
  end
73
71
  end
74
72
  end
75
- end
73
+ end