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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +247 -7
- data/examples/anonymous_auth.rb +6 -3
- data/examples/append_file.rb +40 -0
- data/examples/authenticate.rb +12 -7
- data/examples/delete_file.rb +40 -0
- data/examples/list_directory.rb +45 -0
- data/examples/negotiate.rb +0 -1
- data/examples/negotiate_with_netbios_service.rb +36 -0
- data/examples/net_share_enum_all.rb +30 -0
- data/examples/read_file.rb +39 -0
- data/examples/rename_file.rb +41 -0
- data/examples/tree_connect.rb +2 -4
- data/examples/write_file.rb +40 -0
- data/lib/ruby_smb.rb +5 -0
- data/lib/ruby_smb/client.rb +196 -43
- data/lib/ruby_smb/client/authentication.rb +89 -48
- data/lib/ruby_smb/client/echo.rb +1 -4
- data/lib/ruby_smb/client/negotiation.rb +46 -45
- data/lib/ruby_smb/client/signing.rb +9 -16
- data/lib/ruby_smb/client/tree_connect.rb +8 -13
- data/lib/ruby_smb/client/utils.rb +79 -0
- data/lib/ruby_smb/dcerpc.rb +30 -0
- data/lib/ruby_smb/dcerpc/bind.rb +60 -0
- data/lib/ruby_smb/dcerpc/handle.rb +60 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +41 -0
- data/lib/ruby_smb/dcerpc/request.rb +43 -0
- data/lib/ruby_smb/dcerpc/response.rb +46 -0
- data/lib/ruby_smb/dcerpc/srvsvc.rb +17 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +93 -0
- data/lib/ruby_smb/dcerpc/uuid.rb +28 -0
- data/lib/ruby_smb/dispatcher.rb +7 -3
- data/lib/ruby_smb/dispatcher/base.rb +23 -14
- data/lib/ruby_smb/dispatcher/socket.rb +71 -51
- data/lib/ruby_smb/dispositions.rb +32 -0
- data/lib/ruby_smb/error.rb +24 -18
- data/lib/ruby_smb/field.rb +5 -2
- data/lib/ruby_smb/field/extended_attribute_flag.rb +1 -1
- data/lib/ruby_smb/field/file_time.rb +3 -1
- data/lib/ruby_smb/field/security_descriptor.rb +6 -6
- data/lib/ruby_smb/field/smb2_fileid.rb +11 -0
- data/lib/ruby_smb/field/smb_fea.rb +3 -3
- data/lib/ruby_smb/field/smb_fea_list.rb +3 -3
- data/lib/ruby_smb/field/smb_gea.rb +12 -0
- data/lib/ruby_smb/field/smb_gea_list.rb +13 -0
- data/lib/ruby_smb/field/string16.rb +14 -0
- data/lib/ruby_smb/field/stringz16.rb +3 -7
- data/lib/ruby_smb/field/utime.rb +11 -10
- data/lib/ruby_smb/fscc.rb +12 -0
- data/lib/ruby_smb/fscc/control_codes.rb +26 -0
- data/lib/ruby_smb/{field → fscc}/ea_info_array.rb +12 -14
- data/lib/ruby_smb/fscc/file_attributes.rb +29 -0
- data/lib/ruby_smb/{field → fscc}/file_full_ea_info.rb +5 -5
- data/lib/ruby_smb/fscc/file_information.rb +60 -0
- data/lib/ruby_smb/fscc/file_information/file_both_directory_information.rb +29 -0
- data/lib/ruby_smb/fscc/file_information/file_directory_information.rb +25 -0
- data/lib/ruby_smb/fscc/file_information/file_disposition_information.rb +15 -0
- data/lib/ruby_smb/fscc/file_information/file_full_directory_information.rb +26 -0
- data/lib/ruby_smb/fscc/file_information/file_id_both_directory_information.rb +31 -0
- data/lib/ruby_smb/fscc/file_information/file_id_full_directory_information.rb +28 -0
- data/lib/ruby_smb/fscc/file_information/file_names_information.rb +18 -0
- data/lib/ruby_smb/fscc/file_information/file_rename_information.rb +44 -0
- data/lib/ruby_smb/generic_packet.rb +40 -18
- data/lib/ruby_smb/gss.rb +49 -56
- data/lib/ruby_smb/impersonation_levels.rb +7 -2
- data/lib/ruby_smb/nbss.rb +16 -0
- data/lib/ruby_smb/nbss/negative_session_response.rb +30 -0
- data/lib/ruby_smb/nbss/session_header.rb +13 -0
- data/lib/ruby_smb/nbss/session_request.rb +13 -0
- data/lib/ruby_smb/smb1.rb +20 -17
- data/lib/ruby_smb/smb1/bit_field.rb +3 -0
- data/lib/ruby_smb/smb1/bit_field/create_options.rb +5 -5
- data/lib/ruby_smb/smb1/bit_field/file_status_flags.rb +18 -0
- data/lib/ruby_smb/smb1/bit_field/open2_access_mode.rb +11 -11
- data/lib/ruby_smb/smb1/bit_field/open2_open_mode.rb +1 -1
- data/lib/ruby_smb/smb1/bit_field/optional_support.rb +0 -1
- data/lib/ruby_smb/smb1/bit_field/security_flags.rb +15 -0
- data/lib/ruby_smb/smb1/bit_field/share_access.rb +2 -3
- data/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes.rb +21 -24
- data/lib/ruby_smb/smb1/bit_field/smb_file_attributes.rb +1 -1
- data/lib/ruby_smb/smb1/commands.rb +5 -0
- data/lib/ruby_smb/smb1/create_actions.rb +3 -5
- data/lib/ruby_smb/smb1/file.rb +289 -0
- data/lib/ruby_smb/smb1/oplock_levels.rb +2 -4
- data/lib/ruby_smb/smb1/packet.rb +10 -0
- data/lib/ruby_smb/smb1/packet/close_request.rb +31 -0
- data/lib/ruby_smb/smb1/packet/close_response.rb +28 -0
- data/lib/ruby_smb/smb1/packet/echo_request.rb +5 -7
- data/lib/ruby_smb/smb1/packet/echo_response.rb +5 -7
- data/lib/ruby_smb/smb1/packet/empty_packet.rb +1 -2
- data/lib/ruby_smb/smb1/packet/logoff_request.rb +1 -4
- data/lib/ruby_smb/smb1/packet/logoff_response.rb +1 -4
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +22 -0
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +22 -0
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +62 -0
- data/lib/ruby_smb/smb1/packet/nt_create_andx_response.rb +66 -0
- data/lib/ruby_smb/smb1/packet/nt_trans.rb +1 -2
- data/lib/ruby_smb/smb1/packet/nt_trans/create_request.rb +19 -13
- data/lib/ruby_smb/smb1/packet/nt_trans/create_response.rb +8 -10
- data/lib/ruby_smb/smb1/packet/nt_trans/request.rb +11 -11
- data/lib/ruby_smb/smb1/packet/nt_trans/response.rb +10 -10
- data/lib/ruby_smb/smb1/packet/nt_trans/subcommands.rb +8 -1
- data/lib/ruby_smb/smb1/packet/read_andx_request.rb +84 -0
- data/lib/ruby_smb/smb1/packet/read_andx_response.rb +47 -0
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_request.rb +2 -6
- data/lib/ruby_smb/smb1/packet/session_setup_legacy_response.rb +1 -4
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -6
- data/lib/ruby_smb/smb1/packet/session_setup_response.rb +2 -4
- data/lib/ruby_smb/smb1/packet/trans2.rb +8 -2
- data/lib/ruby_smb/smb1/packet/trans2/data_block.rb +6 -7
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_request.rb +77 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +87 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_information_level.rb +32 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info.rb +45 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_request.rb +77 -0
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +86 -0
- data/lib/ruby_smb/smb1/packet/trans2/open2_request.rb +10 -10
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +10 -12
- data/lib/ruby_smb/smb1/packet/trans2/request.rb +15 -17
- data/lib/ruby_smb/smb1/packet/trans2/request_secondary.rb +8 -10
- data/lib/ruby_smb/smb1/packet/trans2/response.rb +11 -13
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb +66 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +57 -0
- data/lib/ruby_smb/smb1/packet/trans2/subcommands.rb +5 -2
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +4 -6
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +5 -7
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +2 -4
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +2 -4
- data/lib/ruby_smb/smb1/packet/write_andx_request.rb +68 -0
- data/lib/ruby_smb/smb1/packet/write_andx_response.rb +35 -0
- data/lib/ruby_smb/smb1/resource_type.rb +18 -0
- data/lib/ruby_smb/smb1/tree.rb +188 -5
- data/lib/ruby_smb/smb2.rb +16 -11
- data/lib/ruby_smb/smb2/bit_field.rb +1 -0
- data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +1 -1
- data/lib/ruby_smb/smb2/bit_field/session_flags.rb +1 -2
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +4 -6
- data/lib/ruby_smb/smb2/create_context.rb +29 -0
- data/lib/ruby_smb/smb2/file.rb +251 -0
- data/lib/ruby_smb/smb2/info_type.rb +21 -0
- data/lib/ruby_smb/smb2/packet.rb +16 -0
- data/lib/ruby_smb/smb2/packet/close_request.rb +22 -0
- data/lib/ruby_smb/smb2/packet/close_response.rb +29 -0
- data/lib/ruby_smb/smb2/packet/create_request.rb +54 -0
- data/lib/ruby_smb/smb2/packet/create_response.rb +35 -0
- data/lib/ruby_smb/smb2/packet/echo_request.rb +1 -3
- data/lib/ruby_smb/smb2/packet/echo_response.rb +1 -3
- data/lib/ruby_smb/smb2/packet/error_packet.rb +1 -3
- data/lib/ruby_smb/smb2/packet/ioctl_request.rb +54 -0
- data/lib/ruby_smb/smb2/packet/ioctl_response.rb +39 -0
- data/lib/ruby_smb/smb2/packet/logoff_request.rb +1 -4
- data/lib/ruby_smb/smb2/packet/logoff_response.rb +1 -4
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +1 -1
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +1 -1
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +35 -0
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +45 -0
- data/lib/ruby_smb/smb2/packet/read_request.rb +30 -0
- data/lib/ruby_smb/smb2/packet/read_response.rb +26 -0
- data/lib/ruby_smb/smb2/packet/session_setup_request.rb +2 -5
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +4 -7
- data/lib/ruby_smb/smb2/packet/set_info_request.rb +58 -0
- data/lib/ruby_smb/smb2/packet/set_info_response.rb +20 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +3 -4
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +5 -9
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +1 -4
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -4
- data/lib/ruby_smb/smb2/packet/write_request.rb +29 -0
- data/lib/ruby_smb/smb2/packet/write_response.rb +26 -0
- data/lib/ruby_smb/smb2/tree.rb +163 -7
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +459 -120
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +14 -0
- data/spec/lib/ruby_smb/dcerpc/handle_spec.rb +31 -0
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +21 -0
- data/spec/lib/ruby_smb/dcerpc/response_spec.rb +15 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +13 -0
- data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +12 -0
- data/spec/lib/ruby_smb/dispatcher/base_spec.rb +26 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +118 -18
- data/spec/lib/ruby_smb/field/extended_attribute_flag_spec.rb +0 -3
- data/spec/lib/ruby_smb/field/file_time_spec.rb +4 -2
- data/spec/lib/ruby_smb/field/security_descriptor.rb +0 -1
- data/spec/lib/ruby_smb/field/smb2_fileid_spec.rb +10 -0
- data/spec/lib/ruby_smb/field/smb_fea_list_spec.rb +3 -5
- data/spec/lib/ruby_smb/field/smb_gea_list_spec.rb +37 -0
- data/spec/lib/ruby_smb/field/smb_gea_spec.rb +22 -0
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +7 -9
- data/spec/lib/ruby_smb/field/utime_spec.rb +4 -2
- data/spec/lib/ruby_smb/{field → fscc}/ea_info_array_spec.rb +7 -9
- data/spec/lib/ruby_smb/{field → fscc}/file_full_ea_info_spec.rb +2 -3
- data/spec/lib/ruby_smb/fscc/file_information/file_both_directory_information_spec.rb +71 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_directory_information_spec.rb +68 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_disposition_information_spec.rb +26 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_full_directory_information_spec.rb +69 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_id_both_directory_information_spec.rb +72 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_id_full_directory_information_spec.rb +70 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_names_information_spec.rb +41 -0
- data/spec/lib/ruby_smb/fscc/file_information/file_rename_information_spec.rb +133 -0
- data/spec/lib/ruby_smb/fscc/fscc_file_attributes_spec.rb +143 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +46 -21
- data/spec/lib/ruby_smb/nbss/negative_session_response_spec.rb +29 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +30 -0
- data/spec/lib/ruby_smb/nbss/session_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb1/bit_field/create_options_spec.rb +9 -1
- data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/file_status_flags_spec.rb +35 -0
- data/spec/lib/ruby_smb/smb1/bit_field/open2_access_mode_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb1/bit_field/open2_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/open2_open_mode_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/bit_field/optional_support_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/bit_field/security_flags_spec.rb +26 -0
- data/spec/lib/ruby_smb/smb1/bit_field/share_access_spec.rb +0 -3
- data/spec/lib/ruby_smb/smb1/bit_field/smb_ext_file_attributes_spec.rb +20 -39
- data/spec/lib/ruby_smb/smb1/bit_field/smb_file_attributes_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/bit_field/smb_nmpipe_status_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/trans2_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/bit_field/tree_connect_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb1/file_spec.rb +469 -0
- data/spec/lib/ruby_smb/smb1/packet/close_request_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/packet/close_response_spec.rb +45 -0
- data/spec/lib/ruby_smb/smb1/packet/echo_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/echo_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb1/packet/logoff_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/logoff_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/negotiate_response_extended_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/negotiate_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_request_spec.rb +151 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_create_andx_response_spec.rb +157 -0
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_request_spec.rb +13 -6
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/create_response_spec.rb +1 -7
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/request_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/nt_trans/response_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/read_andx_request_spec.rb +149 -0
- data/spec/lib/ruby_smb/smb1/packet/read_andx_response_spec.rb +93 -0
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/session_setup_legacy_response_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +3 -8
- data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_request_spec.rb +180 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +104 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_information_level/find_file_full_directory_info_spec.rb +128 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_request_spec.rb +174 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +102 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_request_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +2 -7
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_secondary_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb +98 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +56 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb +1 -5
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +1 -6
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_request_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_response_spec.rb +1 -4
- data/spec/lib/ruby_smb/smb1/packet/write_andx_request_spec.rb +148 -0
- data/spec/lib/ruby_smb/smb1/packet/write_andx_response_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +409 -7
- data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +1 -1
- data/spec/lib/ruby_smb/smb2/bit_field/share_capabilities_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +0 -2
- data/spec/lib/ruby_smb/smb2/create_context_spec.rb +42 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +233 -0
- data/spec/lib/ruby_smb/smb2/packet/close_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb2/packet/close_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +101 -0
- data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +64 -0
- data/spec/lib/ruby_smb/smb2/packet/echo_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/echo_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/ioctl_request_spec.rb +48 -0
- data/spec/lib/ruby_smb/smb2/packet/logoff_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/logoff_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/query_directory_request_spec.rb +80 -0
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +64 -0
- data/spec/lib/ruby_smb/smb2/packet/read_request_spec.rb +43 -0
- data/spec/lib/ruby_smb/smb2/packet/read_response_spec.rb +50 -0
- data/spec/lib/ruby_smb/smb2/packet/session_setup_request_spec.rb +3 -4
- data/spec/lib/ruby_smb/smb2/packet/session_setup_response_spec.rb +2 -3
- data/spec/lib/ruby_smb/smb2/packet/set_info_request_spec.rb +205 -0
- data/spec/lib/ruby_smb/smb2/packet/set_info_response_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +3 -5
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +1 -2
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_request_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_response_spec.rb +1 -3
- data/spec/lib/ruby_smb/smb2/packet/write_request_spec.rb +51 -0
- data/spec/lib/ruby_smb/smb2/packet/write_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +191 -5
- data/spec/spec_helper.rb +1 -1
- metadata +195 -12
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/smb1/dispositions.rb +0 -36
- data/spec/lib/ruby_smb/dispatcher/dispatcher_base_spec.rb +0 -22
@@ -0,0 +1,30 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Nbss
|
3
|
+
|
4
|
+
|
5
|
+
# Representation of the NetBIOS Negative Session Service Response packet as defined in
|
6
|
+
# [4.3.4 SESSION REQUEST PACKET](https://tools.ietf.org/html/rfc1002)
|
7
|
+
class NegativeSessionResponse < BinData::Record
|
8
|
+
endian :big
|
9
|
+
|
10
|
+
session_header :session_header
|
11
|
+
uint8 :error_code, label: 'Error Code'
|
12
|
+
|
13
|
+
def error_msg
|
14
|
+
case error_code
|
15
|
+
when 0x80
|
16
|
+
'Not listening on called name'
|
17
|
+
when 0x81
|
18
|
+
'Not listening for calling name'
|
19
|
+
when 0x82
|
20
|
+
'Called name not present'
|
21
|
+
when 0x83
|
22
|
+
'Called name present, but insufficient resources'
|
23
|
+
when 0x8F
|
24
|
+
'Unspecified error'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Nbss
|
3
|
+
# Representation of the NetBIOS Session Service Header as defined in
|
4
|
+
# [4.3.1 GENERAL FORMAT OF SESSION PACKETS](https://tools.ietf.org/html/rfc1002)
|
5
|
+
class SessionHeader < BinData::Record
|
6
|
+
endian :big
|
7
|
+
|
8
|
+
uint8 :session_packet_type, label: 'Session Packet Type'
|
9
|
+
uint8 :flags, label: 'Flags', initial_value: 0
|
10
|
+
uint16 :packet_length, label: 'Packet Length'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Nbss
|
3
|
+
# Representation of the NetBIOS Session Service Request packet as defined in
|
4
|
+
# [4.3.2 SESSION REQUEST PACKET](https://tools.ietf.org/html/rfc1002)
|
5
|
+
class SessionRequest < BinData::Record
|
6
|
+
endian :big
|
7
|
+
|
8
|
+
session_header :session_header
|
9
|
+
string :called_name, label: 'Called Name'
|
10
|
+
string :calling_name, label: 'Calling Name'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/ruby_smb/smb1.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module RubySMB
|
2
|
+
# This module adds the namespace for version 1 of the SMB Protocol
|
3
|
+
# as defined in [MS-SMB](https://msdn.microsoft.com/en-us/library/cc246231.aspx)
|
4
|
+
module SMB1
|
5
|
+
# Protocol ID value. Translates to \xFFSMB
|
6
|
+
SMB_PROTOCOL_ID = 0xFF534D42
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
8
|
+
require 'ruby_smb/smb1/create_actions'
|
9
|
+
require 'ruby_smb/smb1/oplock_levels'
|
10
|
+
require 'ruby_smb/smb1/resource_type'
|
11
|
+
require 'ruby_smb/smb1/commands'
|
12
|
+
require 'ruby_smb/smb1/andx_block'
|
13
|
+
require 'ruby_smb/smb1/bit_field'
|
14
|
+
require 'ruby_smb/smb1/smb_header'
|
15
|
+
require 'ruby_smb/smb1/parameter_block'
|
16
|
+
require 'ruby_smb/smb1/data_block'
|
17
|
+
require 'ruby_smb/smb1/dialect'
|
18
|
+
require 'ruby_smb/smb1/packet'
|
19
|
+
require 'ruby_smb/smb1/tree'
|
20
|
+
require 'ruby_smb/smb1/file'
|
21
|
+
end
|
19
22
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module SMB1
|
3
|
+
# Namespace for SMB1 Bit Mask style field definitions
|
3
4
|
module BitField
|
4
5
|
require 'ruby_smb/smb1/bit_field/header_flags'
|
5
6
|
require 'ruby_smb/smb1/bit_field/header_flags2'
|
@@ -18,6 +19,8 @@ module RubySMB
|
|
18
19
|
require 'ruby_smb/smb1/bit_field/smb_nmpipe_status'
|
19
20
|
require 'ruby_smb/smb1/bit_field/share_access'
|
20
21
|
require 'ruby_smb/smb1/bit_field/create_options'
|
22
|
+
require 'ruby_smb/smb1/bit_field/security_flags'
|
23
|
+
require 'ruby_smb/smb1/bit_field/file_status_flags'
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module SMB1
|
3
3
|
module BitField
|
4
|
-
|
5
4
|
# Represents a CreateOptions BitField as used by both the NT_CREATE_ANDX
|
6
5
|
# and the NT_TRANSACT_CREATE Requests. The definition for this field can be found at
|
7
|
-
# [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
|
6
|
+
# [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx) and
|
7
|
+
# [2.2.4.9.1 Client Request Extensions](https://msdn.microsoft.com/en-us/library/cc246332.aspx)
|
8
8
|
class CreateOptions < BinData::Record
|
9
9
|
endian :little
|
10
10
|
bit1 :create_tree_connection, label: 'Create Tree Connection'
|
@@ -27,12 +27,12 @@ module RubySMB
|
|
27
27
|
# Byte Boundary
|
28
28
|
bit1 :open_for_free_space_query, label: 'Open for Free Space Query'
|
29
29
|
bit1 :open_no_recall, label: 'Open No Recall'
|
30
|
-
bit1 :
|
30
|
+
bit1 :open_reparse_point, label: 'Open Reparse Point'
|
31
31
|
bit1 :reserve_opfilter, label: 'Reserve OPFilter'
|
32
32
|
bit4 :reserved, label: 'Reserved Space'
|
33
33
|
# Byte Boundary
|
34
|
-
bit8
|
34
|
+
bit8 :reserved2, label: 'Reserved Space'
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
end
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# Represents a FileStatusFlags BitField as used by both the SMB_COM_NT_CREATE_ANDX
|
5
|
+
# and the NT_TRANSACT_CREATE Responses. The definition for this field can be found at
|
6
|
+
# [2.2.4.9.2 Server Response Extensions](https://msdn.microsoft.com/en-us/library/cc246334.aspx)
|
7
|
+
class FileStatusFlags < BinData::Record
|
8
|
+
endian :little
|
9
|
+
bit5 :reserved, label: 'Reserved'
|
10
|
+
bit1 :reparse_tag, label: 'No Reparse Tag'
|
11
|
+
bit1 :no_substreams, label: 'No Data Sream'
|
12
|
+
bit1 :no_eas, label: 'No Extended Attributes (EAs)'
|
13
|
+
# byte boundary
|
14
|
+
bit8 :reserved2, label: 'Reserved'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,7 +3,7 @@ module RubySMB
|
|
3
3
|
module BitField
|
4
4
|
# The AccessMode bit-field for an SMB1 Open2 Request as defined in
|
5
5
|
# [2.2.6.1.1 Request](https://msdn.microsoft.com/en-us/library/ee441733.aspx)
|
6
|
-
class Open2AccessMode< BinData::Record
|
6
|
+
class Open2AccessMode < BinData::Record
|
7
7
|
endian :little
|
8
8
|
bit1 :reserved2, label: 'Reserved Space'
|
9
9
|
bit3 :sharing_mode, label: 'Sharing Mode'
|
@@ -22,18 +22,18 @@ module RubySMB
|
|
22
22
|
# ReadWrite, and Execute respectively.
|
23
23
|
#
|
24
24
|
# @param mode [Symbol] the access mode to set
|
25
|
-
def set_access_mode(mode
|
25
|
+
def set_access_mode(mode = :r)
|
26
26
|
modes = [:r, :w, :rw, :x]
|
27
|
-
raise ArgumentError, "Mode must be one of #{modes
|
27
|
+
raise ArgumentError, "Mode must be one of #{modes}" unless modes.include? mode
|
28
28
|
case mode
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
when :r
|
30
|
+
self.access_mode = 0
|
31
|
+
when :w
|
32
|
+
self.access_mode = 1
|
33
|
+
when :rw
|
34
|
+
self.access_mode = 2
|
35
|
+
when :x
|
36
|
+
self.access_mode = 3
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -3,7 +3,7 @@ module RubySMB
|
|
3
3
|
module BitField
|
4
4
|
# The OpenMode bit-field for an SMB1 Open2 Request as defined in
|
5
5
|
# [2.2.6.1.1 Request](https://msdn.microsoft.com/en-us/library/ee441733.aspx)
|
6
|
-
class Open2OpenMode< BinData::Record
|
6
|
+
class Open2OpenMode < BinData::Record
|
7
7
|
endian :little
|
8
8
|
bit3 :reserved2, label: 'Reserved Space'
|
9
9
|
bit1 :create_file, label: 'Create File Options'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
module BitField
|
4
|
+
# Represents a SecurityFlags BitField as used by both the SMB_COM_NT_CREATE_ANDX
|
5
|
+
# and the NT_TRANSACT_CREATE Requests. The definition for this field can be found at
|
6
|
+
# [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
|
7
|
+
class SecurityFlags < BinData::Record
|
8
|
+
endian :little
|
9
|
+
bit6 :reserved, label: 'Reserved Space'
|
10
|
+
bit1 :effective_only, label: 'Effective Only'
|
11
|
+
bit1 :context_tracking, label: 'Context Tracking'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module SMB1
|
3
3
|
module BitField
|
4
|
-
|
5
4
|
# Represents a ShareAccess Bit-Field as defined in
|
6
5
|
# [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
|
7
6
|
class ShareAccess < BinData::Record
|
8
|
-
endian
|
7
|
+
endian :little
|
9
8
|
bit5 :reserved, label: 'Reserved Space'
|
10
9
|
bit1 :share_delete, label: 'Share Delete Access'
|
11
10
|
bit1 :share_write, label: 'Share Write Access'
|
@@ -17,4 +16,4 @@ module RubySMB
|
|
17
16
|
end
|
18
17
|
end
|
19
18
|
end
|
20
|
-
end
|
19
|
+
end
|
@@ -2,33 +2,30 @@ module RubySMB
|
|
2
2
|
module SMB1
|
3
3
|
module BitField
|
4
4
|
# The bit-field for SMB1 Extended File Attributes as defined in
|
5
|
-
# [2.2.1.2.3 SMB_EXT_FILE_ATTR](https://msdn.microsoft.com/en-us/library/ee878573.aspx)
|
5
|
+
# [2.2.1.2.3 SMB_EXT_FILE_ATTR](https://msdn.microsoft.com/en-us/library/ee878573.aspx) and
|
6
|
+
# [2.2.1.2.1 Extended File Attribute (SMB_EXT_FILE_ATTR) Extensions](https://msdn.microsoft.com/en-us/library/cc246322.aspx)
|
6
7
|
class SmbExtFileAttributes < BinData::Record
|
7
|
-
endian
|
8
|
-
bit1 :normal,
|
9
|
-
bit1 :reserved,
|
10
|
-
bit1 :archive,
|
11
|
-
bit1 :directory,
|
12
|
-
bit1 :reserved2,
|
13
|
-
bit1 :system,
|
14
|
-
bit1 :hidden,
|
15
|
-
bit1 :read_only,
|
8
|
+
endian :little
|
9
|
+
bit1 :normal, label: 'Normal File'
|
10
|
+
bit1 :reserved, label: 'Reserved Space'
|
11
|
+
bit1 :archive, label: 'Archive'
|
12
|
+
bit1 :directory, label: 'Directory'
|
13
|
+
bit1 :reserved2, label: 'Reserved Space'
|
14
|
+
bit1 :system, label: 'System File'
|
15
|
+
bit1 :hidden, label: 'Hidden File'
|
16
|
+
bit1 :read_only, label: 'Read Only'
|
16
17
|
# Byte boundary
|
17
|
-
|
18
|
-
bit1 :
|
19
|
-
|
20
|
-
bit1 :
|
18
|
+
bit1 :reserved3, label: 'Reserved Space'
|
19
|
+
bit1 :encrypted, label: 'Encrypted'
|
20
|
+
bit1 :not_content_indexed, label: 'Not Content Indexed'
|
21
|
+
bit1 :offline, label: 'Offline'
|
22
|
+
bit1 :compressed, label: 'Compressed File'
|
23
|
+
bit1 :reparse_point, label: 'Reparse Point'
|
24
|
+
bit1 :sparse, label: 'Sparse File'
|
25
|
+
bit1 :temporary, label: 'Temporary File'
|
21
26
|
# Byte Boundary
|
22
|
-
bit8 :
|
23
|
-
|
24
|
-
bit1 :write_through, label: 'Write through'
|
25
|
-
bit1 :reserved6, label: 'Reserved Space'
|
26
|
-
bit1 :no_buffering, label: 'Do not Buffer'
|
27
|
-
bit1 :random_access, label: 'Random Access'
|
28
|
-
bit1 :sequential_scan, label: 'Sequential Access'
|
29
|
-
bit1 :delete_on_close, label: 'Delete on close'
|
30
|
-
bit1 :backup_semantics, label: 'Backup Semantics'
|
31
|
-
bit1 :posix_semantics, label: 'POSIX Semantics'
|
27
|
+
bit8 :reserved4, label: 'Reserved Space'
|
28
|
+
bit8 :reserved5, label: 'Reserved Space'
|
32
29
|
end
|
33
30
|
end
|
34
31
|
end
|
@@ -4,7 +4,7 @@ module RubySMB
|
|
4
4
|
# The Flags bit-field for SMB1 File Attributes as defined in
|
5
5
|
# [2.2.1.2.4 SMB_FILE_ATTRIBUTES](https://msdn.microsoft.com/en-us/library/ee441551.aspx)
|
6
6
|
class SmbFileAttributes < BinData::Record
|
7
|
-
endian
|
7
|
+
endian :little
|
8
8
|
bit2 :reserved, label: 'Reserved Space'
|
9
9
|
bit1 :archive, label: 'Archive'
|
10
10
|
bit1 :directory, label: 'Directory'
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module RubySMB
|
2
2
|
module SMB1
|
3
3
|
module Commands
|
4
|
+
SMB_COM_CLOSE = 0x04
|
4
5
|
SMB_COM_ECHO = 0x2B
|
6
|
+
SMB_COM_READ_ANDX = 0x2E
|
7
|
+
SMB_COM_WRITE_ANDX = 0x2F
|
5
8
|
SMB_COM_TRANSACTION2 = 0x32
|
6
9
|
SMB_COM_TRANSACTION2_SECONDARY = 0x33
|
7
10
|
SMB_COM_TREE_DISCONNECT = 0x71
|
@@ -10,6 +13,8 @@ module RubySMB
|
|
10
13
|
SMB_COM_LOGOFF = 0x74
|
11
14
|
SMB_COM_TREE_CONNECT = 0x75
|
12
15
|
SMB_COM_NT_TRANSACT = 0xA0
|
16
|
+
SMB_COM_NT_TRANSACT_SECONDARY = 0xA1
|
17
|
+
SMB_COM_NT_CREATE_ANDX = 0xA2
|
13
18
|
SMB_COM_NO_ANDX_COMMAND = 0xFF
|
14
19
|
end
|
15
20
|
end
|
@@ -4,19 +4,17 @@ module RubySMB
|
|
4
4
|
# SMB_COM_NT_CREATE_ANDX responses. The definitions for these values can be found at
|
5
5
|
# [2.2.7.1.2 Response](https://msdn.microsoft.com/en-us/library/ee441961.aspx)
|
6
6
|
module CreateActions
|
7
|
-
|
8
7
|
# An existing file was deleted and a new file was created in its place.
|
9
|
-
FILE_SUPERSEDED
|
8
|
+
FILE_SUPERSEDED = 0x00000000
|
10
9
|
|
11
10
|
# An existing file was opened.
|
12
|
-
FILE_OPENED
|
11
|
+
FILE_OPENED = 0x00000001
|
13
12
|
|
14
13
|
# A new file was created.
|
15
14
|
FILE_CREATED = 0x00000002
|
16
15
|
|
17
16
|
# An existing file was overwritten.
|
18
17
|
FILE_OVERWRITEN = 0x00000003
|
19
|
-
|
20
18
|
end
|
21
19
|
end
|
22
|
-
end
|
20
|
+
end
|
@@ -0,0 +1,289 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module SMB1
|
3
|
+
# Represents a file on the Remote server that we can perform
|
4
|
+
# various I/O operations on.
|
5
|
+
class File
|
6
|
+
# The {RubySMB::SMB1::Tree} that this file belong to
|
7
|
+
# @!attribute [rw] tree
|
8
|
+
# @return [RubySMB::SMB1::Tree]
|
9
|
+
attr_accessor :tree
|
10
|
+
|
11
|
+
# The name of the file
|
12
|
+
# @!attribute [rw] name
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :name
|
15
|
+
|
16
|
+
# The {SmbExtFileAttributes} for the file
|
17
|
+
# @!attribute [rw] attributes
|
18
|
+
# @return [RubySMB::SMB1::BitField::SmbExtFileAttributes]
|
19
|
+
attr_accessor :attributes
|
20
|
+
|
21
|
+
# The file ID
|
22
|
+
# @!attribute [rw] fid
|
23
|
+
# @return [Integer]
|
24
|
+
attr_accessor :fid
|
25
|
+
|
26
|
+
# The last access date/time for the file
|
27
|
+
# @!attribute [rw] last_access
|
28
|
+
# @return [DateTime]
|
29
|
+
attr_accessor :last_access
|
30
|
+
|
31
|
+
# The last change date/time for the file
|
32
|
+
# @!attribute [rw] last_change
|
33
|
+
# @return [DateTime]
|
34
|
+
attr_accessor :last_change
|
35
|
+
|
36
|
+
# The last write date/time for the file
|
37
|
+
# @!attribute [rw] last_write
|
38
|
+
# @return [DateTime]
|
39
|
+
attr_accessor :last_write
|
40
|
+
|
41
|
+
# The actual size, in bytes, of the file
|
42
|
+
# @!attribute [rw] size
|
43
|
+
# @return [Integer]
|
44
|
+
attr_accessor :size
|
45
|
+
|
46
|
+
# The size in bytes that the file occupies on disk
|
47
|
+
# @!attribute [rw] size_on_disk
|
48
|
+
# @return [Integer]
|
49
|
+
attr_accessor :size_on_disk
|
50
|
+
|
51
|
+
def initialize(tree:, response:, name:)
|
52
|
+
raise ArgumentError, 'No tree provided' if tree.nil?
|
53
|
+
raise ArgumentError, 'No response provided' if response.nil?
|
54
|
+
raise ArgumentError, 'No file name provided' if name.nil?
|
55
|
+
|
56
|
+
@tree = tree
|
57
|
+
@name = name
|
58
|
+
|
59
|
+
@attributes = response.parameter_block.ext_file_attributes
|
60
|
+
@fid = response.parameter_block.fid
|
61
|
+
@last_access = response.parameter_block.last_access_time.to_datetime
|
62
|
+
@last_change = response.parameter_block.last_change_time.to_datetime
|
63
|
+
@last_write = response.parameter_block.last_write_time.to_datetime
|
64
|
+
@size = response.parameter_block.end_of_file
|
65
|
+
@size_on_disk = response.parameter_block.allocation_size
|
66
|
+
end
|
67
|
+
|
68
|
+
# Appends the supplied data to the end of the file.
|
69
|
+
#
|
70
|
+
# @param data [String] the data to write to the file
|
71
|
+
# @return [WindowsError::ErrorCode] the NTStatus code returned from the operation
|
72
|
+
def append(data:)
|
73
|
+
write(data: data, offset: @size)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Closes the handle to the remote file.
|
77
|
+
#
|
78
|
+
# @return [WindowsError::ErrorCode] the NTStatus code returned by the operation
|
79
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response command is not SMB_COM_CLOSE
|
80
|
+
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
81
|
+
def close
|
82
|
+
close_request = set_header_fields(RubySMB::SMB1::Packet::CloseRequest.new)
|
83
|
+
raw_response = @tree.client.send_recv(close_request)
|
84
|
+
response = RubySMB::SMB1::Packet::CloseResponse.read(raw_response)
|
85
|
+
unless response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_CLOSE
|
86
|
+
raise RubySMB::Error::InvalidPacket, 'Not a CloseResponse packet'
|
87
|
+
end
|
88
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
89
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code.name
|
90
|
+
end
|
91
|
+
response.status_code
|
92
|
+
end
|
93
|
+
|
94
|
+
# Read from the file, a specific number of bytes
|
95
|
+
# from a specific offset. If no parameters are given
|
96
|
+
# it will read the entire file.
|
97
|
+
#
|
98
|
+
# @param bytes [Integer] the number of bytes to read
|
99
|
+
# @param offset [Integer] the byte offset in the file to start reading from
|
100
|
+
# @return [String] the data read from the file
|
101
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response command is not SMB_COM_READ_ANDX
|
102
|
+
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
103
|
+
def read(bytes: @size, offset: 0)
|
104
|
+
atomic_read_size = if bytes > @tree.client.max_buffer_size
|
105
|
+
@tree.client.max_buffer_size
|
106
|
+
else
|
107
|
+
bytes
|
108
|
+
end
|
109
|
+
remaining_bytes = bytes
|
110
|
+
data = ''
|
111
|
+
|
112
|
+
loop do
|
113
|
+
read_request = read_packet(read_length: atomic_read_size, offset: offset)
|
114
|
+
raw_response = @tree.client.send_recv(read_request)
|
115
|
+
response = RubySMB::SMB1::Packet::ReadAndxResponse.read(raw_response)
|
116
|
+
unless response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_READ_ANDX
|
117
|
+
raise RubySMB::Error::InvalidPacket, 'Not a ReadAndxResponse 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
|
+
if response.is_a?(RubySMB::SMB1::Packet::ReadAndxResponse)
|
124
|
+
data << response.data_block.data.to_binary_s
|
125
|
+
else
|
126
|
+
# Returns the current data immediately if we got an empty packet with an
|
127
|
+
# SMB_COM_READ_ANDX command and a STATUS_SUCCESS (just in case)
|
128
|
+
return data
|
129
|
+
end
|
130
|
+
|
131
|
+
remaining_bytes -= atomic_read_size
|
132
|
+
break unless remaining_bytes > 0
|
133
|
+
|
134
|
+
offset += atomic_read_size
|
135
|
+
atomic_read_size = remaining_bytes if remaining_bytes < @tree.client.max_buffer_size
|
136
|
+
end
|
137
|
+
|
138
|
+
data
|
139
|
+
end
|
140
|
+
|
141
|
+
# Crafts the ReadRequest packet to be sent for read operations.
|
142
|
+
#
|
143
|
+
# @param bytes [Integer] the number of bytes to read
|
144
|
+
# @param offset [Integer] the byte offset in the file to start reading from
|
145
|
+
# @return [RubySMB::SMB1::Packet::ReadAndxRequest] the crafted ReadRequest packet
|
146
|
+
def read_packet(read_length: 0, offset: 0)
|
147
|
+
read_request = set_header_fields(RubySMB::SMB1::Packet::ReadAndxRequest.new)
|
148
|
+
read_request.parameter_block.max_count_of_bytes_to_return = read_length
|
149
|
+
read_request.parameter_block.offset = offset
|
150
|
+
read_request
|
151
|
+
end
|
152
|
+
|
153
|
+
def send_recv_read(read_length: 0, offset: 0)
|
154
|
+
read_request = read_packet(read_length: read_length, offset: offset)
|
155
|
+
raw_response = tree.client.send_recv(read_request)
|
156
|
+
response = RubySMB::SMB1::Packet::ReadAndxResponse.read(raw_response)
|
157
|
+
response.data_block.data.to_binary_s
|
158
|
+
end
|
159
|
+
|
160
|
+
# Delete a file on close
|
161
|
+
#
|
162
|
+
# @return [WindowsError::ErrorCode] the NTStatus Response code
|
163
|
+
def delete
|
164
|
+
raw_response = @tree.client.send_recv(delete_packet)
|
165
|
+
response = RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse.read(raw_response)
|
166
|
+
response.status_code
|
167
|
+
end
|
168
|
+
|
169
|
+
# Crafts the SetFileInformationRequest packet to be sent for delete operations.
|
170
|
+
#
|
171
|
+
# @return [RubySMB::SMB1::Packet::Trans2::SetFileInformationRequest] the set info packet
|
172
|
+
def delete_packet
|
173
|
+
delete_request = RubySMB::SMB1::Packet::Trans2::SetFileInformationRequest.new
|
174
|
+
delete_request = @tree.set_header_fields(delete_request)
|
175
|
+
delete_request.data_block.trans2_parameters.fid = @fid
|
176
|
+
passthrough_info_level = RubySMB::Fscc::FileInformation::FILE_DISPOSITION_INFORMATION +
|
177
|
+
RubySMB::Fscc::FileInformation::SMB_INFO_PASSTHROUGH
|
178
|
+
delete_request.data_block.trans2_parameters.information_level = passthrough_info_level
|
179
|
+
delete_request.data_block.trans2_data.info_level_struct.delete_pending = 1
|
180
|
+
set_trans2_params(delete_request)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Write the supplied data to the file at the given offset.
|
184
|
+
#
|
185
|
+
# @param data [String] the data to write to the file
|
186
|
+
# @param offset [Integer] the offset in the file to start writing from
|
187
|
+
# @return [Integer] the count of bytes written
|
188
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response command is not SMB_COM_WRITE_ANDX
|
189
|
+
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus is not STATUS_SUCCESS
|
190
|
+
def write(data:, offset: 0)
|
191
|
+
buffer = data.dup
|
192
|
+
bytes = data.length
|
193
|
+
total_bytes_written = 0
|
194
|
+
|
195
|
+
loop do
|
196
|
+
atomic_write_size = if bytes > @tree.client.max_buffer_size
|
197
|
+
@tree.client.max_buffer_size
|
198
|
+
else
|
199
|
+
bytes
|
200
|
+
end
|
201
|
+
write_request = write_packet(data: buffer.slice!(0, atomic_write_size), offset: offset)
|
202
|
+
raw_response = @tree.client.send_recv(write_request)
|
203
|
+
response = RubySMB::SMB1::Packet::WriteAndxResponse.read(raw_response)
|
204
|
+
unless response.smb_header.command == RubySMB::SMB1::Commands::SMB_COM_WRITE_ANDX
|
205
|
+
raise RubySMB::Error::InvalidPacket, 'Not a WriteAndxResponse packet'
|
206
|
+
end
|
207
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
208
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code.name
|
209
|
+
end
|
210
|
+
bytes_written = response.parameter_block.count_low + (response.parameter_block.count_high << 16)
|
211
|
+
total_bytes_written += bytes_written
|
212
|
+
offset += bytes_written
|
213
|
+
bytes -= bytes_written
|
214
|
+
break unless buffer.length > 0
|
215
|
+
end
|
216
|
+
|
217
|
+
total_bytes_written
|
218
|
+
end
|
219
|
+
|
220
|
+
# Creates the Request packet for the #write command
|
221
|
+
#
|
222
|
+
# @param data [String] the data to write to the file
|
223
|
+
# @param offset [Integer] the offset in the file to start writing from
|
224
|
+
# @return [RubySMB::SMB1::Packet::WriteAndxRequest] the request packet
|
225
|
+
def write_packet(data:'', offset: 0)
|
226
|
+
write_request = set_header_fields(RubySMB::SMB1::Packet::WriteAndxRequest.new)
|
227
|
+
write_request.parameter_block.offset = offset
|
228
|
+
write_request.parameter_block.write_mode.writethrough_mode = 1
|
229
|
+
write_request.data_block.data = data
|
230
|
+
write_request.parameter_block.remaining = write_request.parameter_block.data_length
|
231
|
+
write_request
|
232
|
+
end
|
233
|
+
|
234
|
+
def send_recv_write(data:'', offset: 0)
|
235
|
+
pkt = write_packet(data: data, offset: offset)
|
236
|
+
raw_response = @tree.client.send_recv(pkt)
|
237
|
+
response = RubySMB::SMB1::Packet::WriteAndxResponse.read(raw_response)
|
238
|
+
response.parameter_block.count_low
|
239
|
+
end
|
240
|
+
|
241
|
+
# Rename a file
|
242
|
+
#
|
243
|
+
# @param new_file_name [String] the new name
|
244
|
+
# @return [WindowsError::ErrorCode] the NTStatus Response code
|
245
|
+
def rename(new_file_name)
|
246
|
+
raw_response = tree.client.send_recv(rename_packet(new_file_name))
|
247
|
+
response = RubySMB::SMB1::Packet::Trans2::SetFileInformationResponse.read(raw_response)
|
248
|
+
response.status_code
|
249
|
+
end
|
250
|
+
|
251
|
+
# Crafts the SetFileInformationRequest packet to be sent for rename operations.
|
252
|
+
#
|
253
|
+
# @param new_file_name [String] the new name
|
254
|
+
# @return [RubySMB::SMB1::Packet::Trans2::SetFileInformationRequest] the set info packet
|
255
|
+
def rename_packet(new_file_name)
|
256
|
+
rename_request = RubySMB::SMB1::Packet::Trans2::SetFileInformationRequest.new
|
257
|
+
rename_request = @tree.set_header_fields(rename_request)
|
258
|
+
rename_request.data_block.trans2_parameters.fid = @fid
|
259
|
+
passthrough_info_level = RubySMB::Fscc::FileInformation::FILE_RENAME_INFORMATION +
|
260
|
+
RubySMB::Fscc::FileInformation::SMB_INFO_PASSTHROUGH
|
261
|
+
rename_request.data_block.trans2_parameters.information_level = passthrough_info_level
|
262
|
+
rename_request.data_block.trans2_data.info_level_struct.file_name = new_file_name.encode('utf-16le')
|
263
|
+
set_trans2_params(rename_request)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Sets the header fields that we have to set on every packet
|
267
|
+
# we send for File operations.
|
268
|
+
#
|
269
|
+
# @param request [RubySMB::GenericPacket] the request packet to set fields on
|
270
|
+
# @return [RubySMB::GenericPacket] the modified request packet
|
271
|
+
def set_header_fields(request)
|
272
|
+
request = @tree.set_header_fields(request)
|
273
|
+
request.parameter_block.fid = @fid
|
274
|
+
request
|
275
|
+
end
|
276
|
+
|
277
|
+
# Sets ParameterBlock options for Trans2 requests
|
278
|
+
def set_trans2_params(request)
|
279
|
+
request.parameter_block.total_parameter_count = request.parameter_block.parameter_count
|
280
|
+
request.parameter_block.total_data_count = request.parameter_block.data_count
|
281
|
+
request.parameter_block.max_parameter_count = request.parameter_block.parameter_count
|
282
|
+
request.parameter_block.max_data_count = 16_384
|
283
|
+
request
|
284
|
+
end
|
285
|
+
private :set_trans2_params
|
286
|
+
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|