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
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Packet::SessionSetupResponse do
|
4
|
-
|
5
4
|
subject(:packet) { described_class.new }
|
6
5
|
|
7
6
|
it { is_expected.to respond_to :smb2_header }
|
@@ -32,7 +31,7 @@ RSpec.describe RubySMB::SMB2::Packet::SessionSetupResponse do
|
|
32
31
|
end
|
33
32
|
|
34
33
|
describe '#set_type2_blob' do
|
35
|
-
let(:fake_message) {
|
34
|
+
let(:fake_message) { 'foo' }
|
36
35
|
|
37
36
|
it 'calls the #gss_type2 method to create a blob' do
|
38
37
|
expect(RubySMB::Gss).to receive(:gss_type2).with(fake_message).and_return(fake_message)
|
@@ -51,4 +50,4 @@ RSpec.describe RubySMB::SMB2::Packet::SessionSetupResponse do
|
|
51
50
|
expect(packet.security_buffer_length).to eq fake_message.length
|
52
51
|
end
|
53
52
|
end
|
54
|
-
end
|
53
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::SetInfoRequest do
|
4
|
+
subject(:packet) { described_class.new }
|
5
|
+
|
6
|
+
it { is_expected.to respond_to :smb2_header }
|
7
|
+
it { is_expected.to respond_to :structure_size }
|
8
|
+
it { is_expected.to respond_to :info_type }
|
9
|
+
it { is_expected.to respond_to :file_info_class }
|
10
|
+
it { is_expected.to respond_to :buffer_length }
|
11
|
+
it { is_expected.to respond_to :buffer_offset }
|
12
|
+
it { is_expected.to respond_to :reserved }
|
13
|
+
it { is_expected.to respond_to :additional_information }
|
14
|
+
it { is_expected.to respond_to :file_id }
|
15
|
+
it { is_expected.to respond_to :buffer }
|
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 '#smb2_header' do
|
22
|
+
subject(:header) { packet.smb2_header }
|
23
|
+
|
24
|
+
it 'is a standard SMB2 Header' do
|
25
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have the command set to SMB_INFO' do
|
29
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::SET_INFO
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should not have the response flag set' do
|
33
|
+
expect(header.flags.reply).to eq 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#structure_size' do
|
38
|
+
it 'is a 16-bit field' do
|
39
|
+
expect(packet.structure_size).to be_a BinData::Uint16le
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'has a default value of 33' do
|
43
|
+
expect(packet.structure_size).to eq 33
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#info_type' do
|
48
|
+
it 'is a 8-bit field' do
|
49
|
+
expect(packet.info_type).to be_a BinData::Uint8
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'has a default value of SMB2_0_INFO_FILE' do
|
53
|
+
expect(packet.info_type).to eq RubySMB::SMB2::InfoType::SMB2_0_INFO_FILE
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#file_info_class' do
|
58
|
+
it 'is a 8-bit field' do
|
59
|
+
expect(packet.file_info_class).to be_a BinData::Uint8
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#buffer_length' do
|
64
|
+
it 'is a 32-bit field' do
|
65
|
+
expect(packet.buffer_length).to be_a BinData::Uint32le
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'is set to the buffer size' do
|
69
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_FULL_DIRECTORY_INFORMATION
|
70
|
+
expect(packet.buffer_length).to eq packet.buffer.do_num_bytes
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#buffer_offset' do
|
75
|
+
it 'is a 16-bit field' do
|
76
|
+
expect(packet.buffer_offset).to be_a BinData::Uint16le
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'is set to the buffer size' do
|
80
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_FULL_DIRECTORY_INFORMATION
|
81
|
+
expect(packet.buffer_offset).to eq packet.buffer.abs_offset
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#additional_information' do
|
86
|
+
subject(:additional_information) { packet.additional_information }
|
87
|
+
|
88
|
+
it { is_expected.to respond_to :scope_security_information }
|
89
|
+
it { is_expected.to respond_to :attribute_security_information }
|
90
|
+
it { is_expected.to respond_to :label_security_information }
|
91
|
+
it { is_expected.to respond_to :sacl_security_information }
|
92
|
+
it { is_expected.to respond_to :dacl_security_information }
|
93
|
+
it { is_expected.to respond_to :group_security_information }
|
94
|
+
it { is_expected.to respond_to :owner_security_information }
|
95
|
+
it { is_expected.to respond_to :backup_security_information }
|
96
|
+
|
97
|
+
describe '#scope_security_information' do
|
98
|
+
it 'should be a 1-bit field per the SMB spec' do
|
99
|
+
expect(additional_information.scope_security_information).to be_a BinData::Bit1
|
100
|
+
end
|
101
|
+
|
102
|
+
it_behaves_like 'bit field with one flag set', :scope_security_information, 'V', 0x00000040
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#attribute_security_information' do
|
106
|
+
it 'should be a 1-bit field per the SMB spec' do
|
107
|
+
expect(additional_information.attribute_security_information).to be_a BinData::Bit1
|
108
|
+
end
|
109
|
+
|
110
|
+
it_behaves_like 'bit field with one flag set', :attribute_security_information, 'V', 0x00000020
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#label_security_information' do
|
114
|
+
it 'should be a 1-bit field per the SMB spec' do
|
115
|
+
expect(additional_information.label_security_information).to be_a BinData::Bit1
|
116
|
+
end
|
117
|
+
|
118
|
+
it_behaves_like 'bit field with one flag set', :label_security_information, 'V', 0x00000010
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#sacl_security_information' do
|
122
|
+
it 'should be a 1-bit field per the SMB spec' do
|
123
|
+
expect(additional_information.sacl_security_information).to be_a BinData::Bit1
|
124
|
+
end
|
125
|
+
|
126
|
+
it_behaves_like 'bit field with one flag set', :sacl_security_information, 'V', 0x00000008
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#dacl_security_information' do
|
130
|
+
it 'should be a 1-bit field per the SMB spec' do
|
131
|
+
expect(additional_information.dacl_security_information).to be_a BinData::Bit1
|
132
|
+
end
|
133
|
+
|
134
|
+
it_behaves_like 'bit field with one flag set', :dacl_security_information, 'V', 0x00000004
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#group_security_information' do
|
138
|
+
it 'should be a 1-bit field per the SMB spec' do
|
139
|
+
expect(additional_information.group_security_information).to be_a BinData::Bit1
|
140
|
+
end
|
141
|
+
|
142
|
+
it_behaves_like 'bit field with one flag set', :group_security_information, 'V', 0x00000002
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#owner_security_information' do
|
146
|
+
it 'should be a 1-bit field per the SMB spec' do
|
147
|
+
expect(additional_information.owner_security_information).to be_a BinData::Bit1
|
148
|
+
end
|
149
|
+
|
150
|
+
it_behaves_like 'bit field with one flag set', :owner_security_information, 'V', 0x00000001
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#backup_security_information' do
|
154
|
+
it 'should be a 1-bit field per the SMB spec' do
|
155
|
+
expect(additional_information.backup_security_information).to be_a BinData::Bit1
|
156
|
+
end
|
157
|
+
|
158
|
+
it_behaves_like 'bit field with one flag set', :backup_security_information, 'V', 0x00010000
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#file_id' do
|
163
|
+
it 'is a Smb2Fileid field' do
|
164
|
+
expect(packet.file_id).to be_a RubySMB::Field::Smb2Fileid
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '#buffer' do
|
169
|
+
context 'when file_info_class is set' do
|
170
|
+
it 'is set to a FileDirectoryInformation class with the FILE_DIRECTORY_INFORMATION code' do
|
171
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_DIRECTORY_INFORMATION
|
172
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileDirectoryInformation.new
|
173
|
+
end
|
174
|
+
it 'is set to a FileFullDirectoryInformation class with the FILE_FULL_DIRECTORY_INFORMATION code' do
|
175
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_FULL_DIRECTORY_INFORMATION
|
176
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileFullDirectoryInformation.new
|
177
|
+
end
|
178
|
+
it 'is set to a FileDispositionInformation class with the FILE_DISPOSITION_INFORMATION code' do
|
179
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_DISPOSITION_INFORMATION
|
180
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileDispositionInformation.new
|
181
|
+
end
|
182
|
+
it 'is set to a FileIdFullDirectoryInformation class with the FILE_ID_FULL_DIRECTORY_INFORMATION code' do
|
183
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_ID_FULL_DIRECTORY_INFORMATION
|
184
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileIdFullDirectoryInformation.new
|
185
|
+
end
|
186
|
+
it 'is set to a FileBothDirectoryInformation class with the FILE_BOTH_DIRECTORY_INFORMATION code' do
|
187
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_BOTH_DIRECTORY_INFORMATION
|
188
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileBothDirectoryInformation.new
|
189
|
+
end
|
190
|
+
it 'is set to a FileIdBothDirectoryInformation class with the FILE_ID_BOTH_DIRECTORY_INFORMATION code' do
|
191
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_ID_BOTH_DIRECTORY_INFORMATION
|
192
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileIdBothDirectoryInformation.new
|
193
|
+
end
|
194
|
+
it 'is set to a FileNamesInformation class with the FILE_NAMES_INFORMATION code' do
|
195
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_NAMES_INFORMATION
|
196
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileNamesInformation.new
|
197
|
+
end
|
198
|
+
it 'is set to a FileRenameInformation class with the FILE_RENAME_INFORMATION code' do
|
199
|
+
packet.file_info_class = RubySMB::Fscc::FileInformation::FILE_RENAME_INFORMATION
|
200
|
+
expect(packet.buffer).to eq RubySMB::Fscc::FileInformation::FileRenameInformation.new
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::SetInfoResponse do
|
4
|
+
subject(:packet) { described_class.new }
|
5
|
+
|
6
|
+
it { is_expected.to respond_to :smb2_header }
|
7
|
+
it { is_expected.to respond_to :structure_size }
|
8
|
+
|
9
|
+
it 'is little endian' do
|
10
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#smb2_header' do
|
14
|
+
subject(:header) { packet.smb2_header }
|
15
|
+
|
16
|
+
it 'is a standard SMB Header' do
|
17
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
21
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::SET_INFO
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have the response flag set' do
|
25
|
+
expect(header.flags.reply).to eq 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have a structure size of 17' do
|
30
|
+
expect(packet.structure_size).to eq 2
|
31
|
+
end
|
32
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Packet::TreeConnectRequest do
|
4
|
-
|
5
4
|
subject(:packet) { described_class.new }
|
6
5
|
|
7
6
|
it { is_expected.to respond_to :smb2_header }
|
@@ -11,7 +10,6 @@ RSpec.describe RubySMB::SMB2::Packet::TreeConnectRequest do
|
|
11
10
|
it { is_expected.to respond_to :path_length }
|
12
11
|
it { is_expected.to respond_to :path }
|
13
12
|
|
14
|
-
|
15
13
|
it 'is little endian' do
|
16
14
|
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
17
15
|
end
|
@@ -33,8 +31,8 @@ RSpec.describe RubySMB::SMB2::Packet::TreeConnectRequest do
|
|
33
31
|
end
|
34
32
|
|
35
33
|
describe '#encode_path' do
|
36
|
-
let(:path) {
|
37
|
-
let(:encoded_path) { path.encode(
|
34
|
+
let(:path) { '\\192.168.1.1\\example' }
|
35
|
+
let(:encoded_path) { path.encode('utf-16le').force_encoding('binary') }
|
38
36
|
|
39
37
|
it 'sets the path string to a UTF-16LE version of the supplied string' do
|
40
38
|
packet.encode_path(path)
|
@@ -46,4 +44,4 @@ RSpec.describe RubySMB::SMB2::Packet::TreeConnectRequest do
|
|
46
44
|
expect(packet.path_length).to eq encoded_path.length
|
47
45
|
end
|
48
46
|
end
|
49
|
-
end
|
47
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Packet::TreeConnectResponse do
|
4
|
-
|
5
4
|
subject(:packet) { described_class.new }
|
6
5
|
|
7
6
|
it { is_expected.to respond_to :smb2_header }
|
@@ -54,4 +53,4 @@ RSpec.describe RubySMB::SMB2::Packet::TreeConnectResponse do
|
|
54
53
|
expect(packet.access_rights).to be_a RubySMB::SMB2::BitField::FileAccessMask
|
55
54
|
end
|
56
55
|
end
|
57
|
-
end
|
56
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectRequest do
|
4
|
-
|
5
4
|
subject(:packet) { described_class.new }
|
6
5
|
|
7
6
|
it { is_expected.to respond_to :smb2_header }
|
@@ -26,5 +25,4 @@ RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectRequest do
|
|
26
25
|
expect(header.flags.reply).to eq 0
|
27
26
|
end
|
28
27
|
end
|
29
|
-
|
30
|
-
end
|
28
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectResponse do
|
4
|
-
|
5
4
|
subject(:packet) { described_class.new }
|
6
5
|
|
7
6
|
it { is_expected.to respond_to :smb2_header }
|
@@ -26,5 +25,4 @@ RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectResponse do
|
|
26
25
|
expect(header.flags.reply).to eq 1
|
27
26
|
end
|
28
27
|
end
|
29
|
-
|
30
|
-
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::WriteRequest do
|
4
|
+
subject(:packet) { described_class.new }
|
5
|
+
|
6
|
+
it { is_expected.to respond_to :smb2_header }
|
7
|
+
it { is_expected.to respond_to :structure_size }
|
8
|
+
it { is_expected.to respond_to :data_offset }
|
9
|
+
it { is_expected.to respond_to :flags }
|
10
|
+
it { is_expected.to respond_to :write_length }
|
11
|
+
it { is_expected.to respond_to :write_offset }
|
12
|
+
it { is_expected.to respond_to :file_id }
|
13
|
+
it { is_expected.to respond_to :channel }
|
14
|
+
it { is_expected.to respond_to :remaining_bytes }
|
15
|
+
it { is_expected.to respond_to :channel_offset }
|
16
|
+
it { is_expected.to respond_to :channel_length }
|
17
|
+
it { is_expected.to respond_to :buffer }
|
18
|
+
|
19
|
+
it 'is little endian' do
|
20
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#smb2_header' do
|
24
|
+
subject(:header) { packet.smb2_header }
|
25
|
+
|
26
|
+
it 'is a standard SMB Header' do
|
27
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
31
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::WRITE
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should not have the response flag set' do
|
35
|
+
expect(header.flags.reply).to eq 0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should have a structure size of 49' do
|
40
|
+
expect(packet.structure_size).to eq 49
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'stores the offset of the write buffer in #data_offset' do
|
44
|
+
expect(packet.data_offset).to eq packet.buffer.abs_offset
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'stores the length of the write buffer in #write_length' do
|
48
|
+
packet.buffer = 'hello'
|
49
|
+
expect(packet.write_length).to eq packet.buffer.length
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::WriteResponse do
|
4
|
+
subject(:packet) { described_class.new }
|
5
|
+
|
6
|
+
it { is_expected.to respond_to :smb2_header }
|
7
|
+
it { is_expected.to respond_to :structure_size }
|
8
|
+
it { is_expected.to respond_to :write_count }
|
9
|
+
it { is_expected.to respond_to :remaining_bytes }
|
10
|
+
it { is_expected.to respond_to :channel_offset }
|
11
|
+
it { is_expected.to respond_to :channel_length }
|
12
|
+
|
13
|
+
|
14
|
+
it 'is little endian' do
|
15
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#smb2_header' do
|
19
|
+
subject(:header) { packet.smb2_header }
|
20
|
+
|
21
|
+
it 'is a standard SMB Header' do
|
22
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
26
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::WRITE
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have the response flag set' do
|
30
|
+
expect(header.flags.reply).to eq 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have a structure size of 49' do
|
35
|
+
expect(packet.structure_size).to eq 17
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe RubySMB::SMB2::Tree do
|
4
|
-
let(:sock)
|
4
|
+
let(:sock) { double('Socket', peeraddr: '192.168.1.5') }
|
5
5
|
let(:dispatcher) { RubySMB::Dispatcher::Socket.new(sock) }
|
6
6
|
|
7
7
|
let(:client) { RubySMB::Client.new(dispatcher, username: 'msfadmin', password: 'msfadmin') }
|
@@ -14,8 +14,12 @@ RSpec.describe RubySMB::SMB2::Tree do
|
|
14
14
|
packet.share_type = 0x01
|
15
15
|
packet
|
16
16
|
}
|
17
|
+
|
18
|
+
let(:disco_req) { RubySMB::SMB2::Packet::TreeDisconnectRequest.new }
|
19
|
+
let(:disco_resp) { RubySMB::SMB2::Packet::TreeDisconnectResponse.new }
|
20
|
+
|
17
21
|
subject(:tree) {
|
18
|
-
described_class.new(client:client, share:path, response:response
|
22
|
+
described_class.new(client: client, share: path, response: response)
|
19
23
|
}
|
20
24
|
|
21
25
|
it { is_expected.to respond_to :client }
|
@@ -36,9 +40,6 @@ RSpec.describe RubySMB::SMB2::Tree do
|
|
36
40
|
end
|
37
41
|
|
38
42
|
describe '#disconnect!' do
|
39
|
-
let(:disco_req) { RubySMB::SMB2::Packet::TreeDisconnectRequest.new }
|
40
|
-
let(:disco_resp) { RubySMB::SMB2::Packet::TreeDisconnectResponse.new }
|
41
|
-
|
42
43
|
it 'sends a TreeDisconnectRequest with the Tree ID in the header' do
|
43
44
|
allow(RubySMB::SMB2::Packet::TreeDisconnectRequest).to receive(:new).and_return(disco_req)
|
44
45
|
modified_req = disco_req
|
@@ -52,4 +53,189 @@ RSpec.describe RubySMB::SMB2::Tree do
|
|
52
53
|
expect(tree.disconnect!).to eq disco_resp.status_code
|
53
54
|
end
|
54
55
|
end
|
56
|
+
|
57
|
+
describe '#set_header_fields' do
|
58
|
+
let(:modified_request) { tree.set_header_fields(disco_req) }
|
59
|
+
it 'adds the TreeID to the header' do
|
60
|
+
expect(modified_request.smb2_header.tree_id).to eq tree.id
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'sets the credit charge to 1' do
|
64
|
+
expect(modified_request.smb2_header.credit_charge).to eq 1
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'sets the credits to 256' do
|
68
|
+
expect(modified_request.smb2_header.credits).to eq 256
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#open_directory_packet' do
|
73
|
+
describe 'directory name' do
|
74
|
+
it 'uses a null byte of nothing is passed in' do
|
75
|
+
expect(tree.open_directory_packet.name).to eq "\x00".encode('UTF-16LE')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'sets the #name_length to 0 if no name is passed in' do
|
79
|
+
expect(tree.open_directory_packet.name_length).to eq 0
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'encodes any supplied file name in UTF-16LE' do
|
83
|
+
name = 'hello.txt'
|
84
|
+
expect(tree.open_directory_packet(directory: name).name).to eq name.encode('UTF-16LE')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'disposition' do
|
89
|
+
it 'defaults to FILE_OPEN' do
|
90
|
+
expect(tree.open_directory_packet.create_disposition).to eq RubySMB::Dispositions::FILE_OPEN
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'can take the Disposition as an argument' do
|
94
|
+
expect(tree.open_directory_packet(disposition: RubySMB::Dispositions::FILE_OPEN_IF).create_disposition).to eq RubySMB::Dispositions::FILE_OPEN_IF
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'impersonation level' do
|
99
|
+
it 'defaults to SEC_IMPERSONATE' do
|
100
|
+
expect(tree.open_directory_packet.impersonation_level).to eq RubySMB::ImpersonationLevels::SEC_IMPERSONATE
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'can take the Impersonation Level as an argument' do
|
104
|
+
expect(tree.open_directory_packet(impersonation: RubySMB::ImpersonationLevels::SEC_DELEGATE).impersonation_level).to eq RubySMB::ImpersonationLevels::SEC_DELEGATE
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'RWD access permissions' do
|
109
|
+
it 'will set the read permission from the parameters' do
|
110
|
+
expect(tree.open_directory_packet(read: true).share_access.read_access).to eq 1
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'will set the write permission from the parameters' do
|
114
|
+
expect(tree.open_directory_packet(write: true).share_access.write_access).to eq 1
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'will set the delete permission from the parameters' do
|
118
|
+
expect(tree.open_directory_packet(delete: true).share_access.delete_access).to eq 1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe '#open_directory' do
|
124
|
+
let(:create_req) { RubySMB::SMB2::Packet::CreateRequest.new }
|
125
|
+
let(:create_response) { RubySMB::SMB2::Packet::CreateResponse.new }
|
126
|
+
|
127
|
+
it 'sends the create request packet and gets a response back' do
|
128
|
+
allow(tree).to receive(:open_directory_packet).and_return(create_req)
|
129
|
+
expect(client).to receive(:send_recv).with(create_req).and_return(create_response.to_binary_s)
|
130
|
+
tree.open_directory
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#list' do
|
135
|
+
let(:create_res) { double('create response') }
|
136
|
+
let(:query_dir_req) { RubySMB::SMB2::Packet::QueryDirectoryRequest.new }
|
137
|
+
let(:query_dir_res) { RubySMB::SMB2::Packet::QueryDirectoryResponse.new }
|
138
|
+
|
139
|
+
before :example do
|
140
|
+
allow(tree).to receive(:open_directory).and_return(create_res)
|
141
|
+
allow(create_res).to receive(:file_id)
|
142
|
+
allow(RubySMB::SMB2::Packet::QueryDirectoryRequest).to receive(:new).and_return(query_dir_req)
|
143
|
+
allow(client).to receive(:send_recv)
|
144
|
+
allow(RubySMB::SMB2::Packet::QueryDirectoryResponse).to receive(:read).and_return(query_dir_res)
|
145
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NO_MORE_FILES.value
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'calls #open_directory' do
|
149
|
+
dir = '/dir'
|
150
|
+
expect(tree).to receive(:open_directory).with(directory: dir).and_return(create_res)
|
151
|
+
tree.list(directory: dir)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'uses the File ID from the create response' do
|
155
|
+
file_id = RubySMB::Field::Smb2Fileid.new
|
156
|
+
allow(create_res).to receive(:file_id).and_return(file_id)
|
157
|
+
allow(client).to receive(:send_recv) do |packet|
|
158
|
+
expect(packet.file_id).to eq file_id
|
159
|
+
end
|
160
|
+
tree.list
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'sets the default QueryDirectoryRequest values' do
|
164
|
+
allow(client).to receive(:send_recv) do |packet|
|
165
|
+
expect(packet.file_information_class).to eq RubySMB::Fscc::FileInformation::FileIdFullDirectoryInformation::CLASS_LEVEL
|
166
|
+
expect(packet.name).to eq '*'.encode('UTF-16LE')
|
167
|
+
expect(packet.output_length).to eq 65_535
|
168
|
+
end
|
169
|
+
tree.list
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'sets QueryDirectoryRequest #name field to the pattern passed as argument' do
|
173
|
+
pattern = '/dir/*/'.encode('UTF-16LE')
|
174
|
+
allow(client).to receive(:send_recv) do |packet|
|
175
|
+
expect(packet.name).to eq pattern
|
176
|
+
end
|
177
|
+
tree.list(pattern: pattern)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'sets QueryDirectoryRequest #file_information_class field to the type passed as argument' do
|
181
|
+
type = RubySMB::Fscc::FileInformation::FileDirectoryInformation
|
182
|
+
allow(client).to receive(:send_recv) do |packet|
|
183
|
+
expect(packet.file_information_class).to eq type::CLASS_LEVEL
|
184
|
+
end
|
185
|
+
tree.list(type: type)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'calls #set_header_fields' do
|
189
|
+
expect(tree).to receive(:set_header_fields).with(query_dir_req).and_call_original
|
190
|
+
tree.list
|
191
|
+
end
|
192
|
+
|
193
|
+
let(:file1) { double('file information') }
|
194
|
+
let(:file2) { double('file information') }
|
195
|
+
|
196
|
+
it 'returns the expected file information' do
|
197
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_SUCCESS.value
|
198
|
+
allow(query_dir_res).to receive(:results) do |_type|
|
199
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NO_MORE_FILES.value
|
200
|
+
[file1]
|
201
|
+
end
|
202
|
+
expect(tree.list).to eq([file1])
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when multiple requests are needed to retrieve the full directory list' do
|
206
|
+
before :example do
|
207
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_SUCCESS.value
|
208
|
+
first_query = true
|
209
|
+
allow(query_dir_res).to receive(:results) do |_type|
|
210
|
+
if first_query
|
211
|
+
first_query = false
|
212
|
+
[file1]
|
213
|
+
else
|
214
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NO_MORE_FILES.value
|
215
|
+
[file2]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'returns the expected file information' do
|
221
|
+
expect(tree.list).to eq([file1] + [file2])
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'resets the message ID between the requests' do
|
225
|
+
allow(client).to receive(:send_recv) do |packet|
|
226
|
+
expect(packet.smb2_header.message_id).to eq 0
|
227
|
+
packet.smb2_header.message_id = 1
|
228
|
+
end
|
229
|
+
tree.list
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when an unexpected status code is received' do
|
234
|
+
it 'raises an exception' do
|
235
|
+
query_dir_res.smb2_header.nt_status = WindowsError::NTStatus::STATUS_FILE_NOT_AVAILABLE.value
|
236
|
+
expect { tree.list }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
55
241
|
end
|