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,93 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
module Srvsvc
|
4
|
+
|
5
|
+
#https://msdn.microsoft.com/en-us/library/cc247293.aspx
|
6
|
+
|
7
|
+
class NetShareEnumAll < BinData::Record
|
8
|
+
Opnum = 0xF
|
9
|
+
|
10
|
+
endian :little
|
11
|
+
|
12
|
+
uint32 :referent_id, initial_value: 0x00000001
|
13
|
+
uint32 :max_count, initial_value: -> { server_unc.do_num_bytes / 2 }
|
14
|
+
uint32 :offset, initial_value: 0
|
15
|
+
uint32 :actual_count, initial_value: -> {max_count}
|
16
|
+
stringz16 :server_unc, pad_front: false, read_length: -> { actual_count * 2 },
|
17
|
+
initial_value: -> {host.encode('utf-16le')}
|
18
|
+
|
19
|
+
uint32 :level, initial_value: 1
|
20
|
+
|
21
|
+
uint32 :ctr, initial_value: 1
|
22
|
+
uint32 :ctr_referent_id, initial_value: 0x00000001
|
23
|
+
uint32 :ctr_count, initial_value: 0
|
24
|
+
uint32 :pointer_to_array, initial_value: 0
|
25
|
+
|
26
|
+
uint32 :max_buffer, initial_value: 4294967295
|
27
|
+
|
28
|
+
uint32 :resume_referent_id, initial_value: 0x00000001
|
29
|
+
uint32 :resume_handle, initial_value: 0
|
30
|
+
|
31
|
+
def self.parse_response(response)
|
32
|
+
|
33
|
+
shares = []
|
34
|
+
|
35
|
+
res = response.dup
|
36
|
+
win_error = res.slice!(-4, 4).unpack("V")[0]
|
37
|
+
|
38
|
+
if win_error != 0
|
39
|
+
raise RuntimeError, "Invalid DCERPC response: win_error = #{win_error}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Remove unused data
|
43
|
+
res.slice!(0, 12) # level, CTR header, Reference ID of CTR
|
44
|
+
share_count = res.slice!(0, 4).unpack("V")[0]
|
45
|
+
res.slice!(0, 4) # Reference ID of CTR1
|
46
|
+
share_max_count = res.slice!(0, 4).unpack("V")[0]
|
47
|
+
|
48
|
+
if share_max_count != share_count
|
49
|
+
raise RuntimeError, "Invalid DCERPC response: count != count max (#{share_count}/#{share_max_count})"
|
50
|
+
end
|
51
|
+
|
52
|
+
# ReferenceID / Type / ReferenceID of Comment
|
53
|
+
types = res.slice!(0, share_count * 12).scan(/.{12}/n).map { |a| a[4, 2].unpack("v")[0] }
|
54
|
+
|
55
|
+
share_count.times do |t|
|
56
|
+
length, offset, max_length = res.slice!(0, 12).unpack("VVV")
|
57
|
+
if offset != 0
|
58
|
+
raise RuntimeError, "Invalid DCERPC response: offset != 0 (#{offset})"
|
59
|
+
end
|
60
|
+
|
61
|
+
if length != max_length
|
62
|
+
raise RuntimeError, "Invalid DCERPC response: length !=max_length (#{length}/#{max_length})"
|
63
|
+
end
|
64
|
+
name = res.slice!(0, 2 * length).gsub('\x00', '')
|
65
|
+
res.slice!(0, 2) if length % 2 == 1 # pad
|
66
|
+
|
67
|
+
comment_length, comment_offset, comment_max_length = res.slice!(0, 12).unpack("VVV")
|
68
|
+
|
69
|
+
if comment_offset != 0
|
70
|
+
raise RuntimeError, "Invalid DCERPC response: comment_offset != 0 (#{comment_offset})"
|
71
|
+
end
|
72
|
+
|
73
|
+
if comment_length != comment_max_length
|
74
|
+
raise RuntimeError, "Invalid DCERPC response: comment_length != comment_max_length (#{comment_length}/#{comment_max_length})"
|
75
|
+
end
|
76
|
+
|
77
|
+
comment = res.slice!(0, 2 * comment_length)
|
78
|
+
|
79
|
+
res.slice!(0, 2) if comment_length % 2 == 1 # pad
|
80
|
+
|
81
|
+
name = name.gsub("\x00", "")
|
82
|
+
s_type = ['DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY'][types[t]].gsub("\x00", "")
|
83
|
+
comment = comment.gsub("\x00", "")
|
84
|
+
|
85
|
+
shares << [name, s_type, comment]
|
86
|
+
end
|
87
|
+
|
88
|
+
shares
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Dcerpc
|
3
|
+
|
4
|
+
#https://msdn.microsoft.com/en-us/library/windows/desktop/aa379358(v=vs.85).aspx
|
5
|
+
class Uuid < BinData::Primitive
|
6
|
+
uint32le :time_low
|
7
|
+
uint16le :time_mid
|
8
|
+
uint16le :time_hi_and_version
|
9
|
+
|
10
|
+
uint16be :clock_seq_hi_and_res
|
11
|
+
uint48be :node
|
12
|
+
|
13
|
+
def get
|
14
|
+
self.to_binary_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def set(uuid_string)
|
18
|
+
components = uuid_string.split('-')
|
19
|
+
self.time_low = components[0].hex
|
20
|
+
self.time_mid = components[1].hex
|
21
|
+
self.time_hi_and_version = components[2].hex
|
22
|
+
self.clock_seq_hi_and_res = components[3].hex
|
23
|
+
self.node = components[4].hex
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/ruby_smb/dispatcher.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
module RubySMB
|
2
|
-
|
3
|
-
|
1
|
+
module RubySMB
|
2
|
+
# Namespace for all of the packet Dispatcher code. This is what
|
3
|
+
# handles network level transport.
|
4
|
+
module Dispatcher
|
5
|
+
require 'ruby_smb/dispatcher/base'
|
6
|
+
require 'ruby_smb/dispatcher/socket'
|
7
|
+
end
|
4
8
|
end
|
@@ -1,18 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module RubySMB
|
2
|
+
module Dispatcher
|
3
|
+
# Provides the base class for the packet dispatcher.
|
4
|
+
class Base
|
5
|
+
# Creates a NetBIOS Session Service (NBSS) header
|
6
|
+
#
|
7
|
+
# @param packet [#do_num_bytes] the packet to be sent
|
8
|
+
# @return [String] NBSS header to go in front of `packet`
|
9
|
+
def nbss(packet)
|
10
|
+
nbss = RubySMB::Nbss::SessionHeader.new
|
11
|
+
nbss.session_packet_type = RubySMB::Nbss::SESSION_MESSAGE
|
12
|
+
nbss.packet_length = packet.do_num_bytes
|
13
|
+
nbss.to_binary_s
|
14
|
+
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
16
|
+
# @abstract
|
17
|
+
def send_packet(_packet)
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
13
20
|
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
# @abstract
|
22
|
+
def recv_packet
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
@@ -1,62 +1,82 @@
|
|
1
1
|
require 'socket'
|
2
|
+
module RubySMB
|
3
|
+
module Dispatcher
|
4
|
+
# This class provides a wrapper around a Socket for the packet Dispatcher.
|
5
|
+
# It allows for dependency injection of different Socket implementations.
|
6
|
+
class Socket < RubySMB::Dispatcher::Base
|
7
|
+
READ_TIMEOUT = 30
|
2
8
|
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
# @!attribute [rw] tcp_socket
|
8
|
-
# @return [IO]
|
9
|
-
attr_accessor :tcp_socket
|
10
|
-
|
11
|
-
# @param tcp_socket [IO]
|
12
|
-
def initialize(tcp_socket)
|
13
|
-
@tcp_socket = tcp_socket
|
14
|
-
if @tcp_socket.respond_to?(:setsockopt)
|
15
|
-
@tcp_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
16
|
-
end
|
17
|
-
end
|
9
|
+
# The underlying socket that we select on
|
10
|
+
# @!attribute [rw] tcp_socket
|
11
|
+
# @return [IO]
|
12
|
+
attr_accessor :tcp_socket
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
14
|
+
# The read timeout
|
15
|
+
# @!attribute [rw] read_timeout
|
16
|
+
# @return [Integer]
|
17
|
+
attr_accessor :read_timeout
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
begin
|
31
|
-
while bytes_written < data.size
|
32
|
-
bytes_written += @tcp_socket.write(data[bytes_written..-1])
|
19
|
+
# @param tcp_socket [IO]
|
20
|
+
def initialize(tcp_socket, read_timeout: READ_TIMEOUT)
|
21
|
+
@tcp_socket = tcp_socket
|
22
|
+
@tcp_socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true) if @tcp_socket.respond_to?(:setsockopt)
|
23
|
+
@read_timeout = read_timeout
|
33
24
|
end
|
34
|
-
rescue IOError, Errno::ECONNABORTED, Errno::ECONNRESET => e
|
35
|
-
raise RubySMB::Error::CommunicationError, "An error occured writing to the Socket"
|
36
|
-
end
|
37
|
-
nil
|
38
|
-
end
|
39
25
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def recv_packet
|
45
|
-
begin
|
46
|
-
IO.select([@tcp_socket])
|
47
|
-
nbss_header = @tcp_socket.read(4) # Length of NBSS header. TODO: remove to a constant
|
48
|
-
if nbss_header.nil?
|
49
|
-
raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
|
50
|
-
else
|
51
|
-
length = nbss_header.unpack('N').first
|
26
|
+
# @param host [String] passed to TCPSocket.new
|
27
|
+
# @param port [Fixnum] passed to TCPSocket.new
|
28
|
+
def self.connect(host, port: 445, socket: TCPSocket.new(host, port))
|
29
|
+
new(socket)
|
52
30
|
end
|
53
|
-
IO.select([@tcp_socket])
|
54
|
-
data = @tcp_socket.read(length)
|
55
|
-
data << @tcp_socket.read(length - data.length) while data.length < length
|
56
31
|
|
57
|
-
|
58
|
-
|
59
|
-
|
32
|
+
# @param packet [SMB2::Packet,#to_s]
|
33
|
+
# @param nbss [Boolean] wether to include the NetBIOS Session header
|
34
|
+
# @return [void]
|
35
|
+
def send_packet(packet, nbss_header: true)
|
36
|
+
data = nbss_header ? nbss(packet) : ''
|
37
|
+
data << packet.to_binary_s
|
38
|
+
bytes_written = 0
|
39
|
+
begin
|
40
|
+
while bytes_written < data.size
|
41
|
+
bytes_written += @tcp_socket.write(data[bytes_written..-1])
|
42
|
+
end
|
43
|
+
rescue IOError, Errno::ECONNABORTED, Errno::ECONNRESET => e
|
44
|
+
raise RubySMB::Error::CommunicationError, "An error occured writing to the Socket: #{e.message}"
|
45
|
+
end
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
# Read a packet off the wire and parse it into a string
|
50
|
+
#
|
51
|
+
# @param full_response [Boolean] whether to include the NetBios Session Service header in the repsonse
|
52
|
+
# @return [String] the raw response (including the NetBios Session Service header if full_response is true)
|
53
|
+
# @raise [RubySMB::Error::NetBiosSessionService] if there's an error reading the first 4 bytes,
|
54
|
+
# which are assumed to be the NetBiosSessionService header.
|
55
|
+
# @raise [RubySMB::Error::CommunicationError] if the read timeout expires or an error occurs when reading the socket
|
56
|
+
def recv_packet(full_response: false)
|
57
|
+
if IO.select([@tcp_socket], nil, nil, @read_timeout).nil?
|
58
|
+
raise RubySMB::Error::CommunicationError, "Read timeout expired when reading from the Socket (timeout=#{@read_timeout})"
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
62
|
+
nbss_header = RubySMB::Nbss::SessionHeader.read(@tcp_socket)
|
63
|
+
rescue IOError
|
64
|
+
raise ::RubySMB::Error::NetBiosSessionService, 'NBSS Header is missing'
|
65
|
+
end
|
66
|
+
|
67
|
+
length = nbss_header.packet_length
|
68
|
+
data = full_response ? nbss_header.to_binary_s : ''
|
69
|
+
if length > 0
|
70
|
+
if IO.select([@tcp_socket], nil, nil, @read_timeout).nil?
|
71
|
+
raise RubySMB::Error::CommunicationError, "Read timeout expired when reading from the Socket (timeout=#{@read_timeout})"
|
72
|
+
end
|
73
|
+
data << @tcp_socket.read(length)
|
74
|
+
data << @tcp_socket.read(length - data.length) while data.length < length
|
75
|
+
end
|
76
|
+
data
|
77
|
+
rescue Errno::EINVAL, Errno::ECONNABORTED, Errno::ECONNRESET, TypeError, NoMethodError => e
|
78
|
+
raise RubySMB::Error::CommunicationError, "An error occured reading from the Socket #{e.message}"
|
79
|
+
end
|
60
80
|
end
|
61
81
|
end
|
62
82
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RubySMB
|
2
|
+
# This module holds the Create Dispositions used in NT_TRANSACT_CREATE and
|
3
|
+
# SMB_COM_NT_CREATE_ANDX requests. The definitions for these values can be found at
|
4
|
+
# [2.2.4.64.1 Request](https://msdn.microsoft.com/en-us/library/ee442175.aspx)
|
5
|
+
module Dispositions
|
6
|
+
# If the file already exists, it SHOULD be superseded (overwritten).
|
7
|
+
# If it does not already exist, it SHOULD be created.
|
8
|
+
FILE_SUPERSEDE = 0x00000000
|
9
|
+
|
10
|
+
# If the file already exists, it SHOULD be opened rather than creating a new file.
|
11
|
+
# If the file does not already exist, the operation MUST fail.
|
12
|
+
FILE_OPEN = 0x00000001
|
13
|
+
|
14
|
+
# If the file already exists, the operation MUST fail.
|
15
|
+
# If the file does not already exist, it SHOULD be created.
|
16
|
+
FILE_CREATE = 0x00000002
|
17
|
+
|
18
|
+
# If the file already exists, it SHOULD be opened.
|
19
|
+
# If the file does not already exist, it SHOULD be created.
|
20
|
+
FILE_OPEN_IF = 0x00000003
|
21
|
+
|
22
|
+
# If the file already exists, it SHOULD be opened and truncated.
|
23
|
+
# If the file does not already exist, the operation MUST fail.
|
24
|
+
# The client MUST open the file with at least GENERIC_WRITE access for the command to succeed.
|
25
|
+
FILE_OVERWRITE = 0x00000004
|
26
|
+
|
27
|
+
# If the file already exists, it SHOULD be opened and truncated.
|
28
|
+
# If the file does not already exist, it SHOULD be created.
|
29
|
+
# The client MUST open the file with at least GENERIC_WRITE access.
|
30
|
+
FILE_OVERWRITE_IF = 0x00000005
|
31
|
+
end
|
32
|
+
end
|
data/lib/ruby_smb/error.rb
CHANGED
@@ -1,24 +1,30 @@
|
|
1
|
-
module RubySMB
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module RubySMB
|
2
|
+
# Contains all the RubySMB specific Error classes.
|
3
|
+
module Error
|
4
|
+
# Base class for RubySMB errors
|
5
|
+
class RubySMBError < StandardError; end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# Raised when there is a length or formatting issue with an ASN1-encoded string
|
8
|
+
# @see https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
|
9
|
+
# @todo Find an SMB-specific link for ASN1 above
|
10
|
+
class ASN1Encoding < RubySMBError; end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
# Raised when there is a problem with communication over NetBios Session Service
|
13
|
+
# @see https://wiki.wireshark.org/NetBIOS/NBSS
|
14
|
+
class NetBiosSessionService < RubySMBError; end
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
# Raised when trying to parse raw binary into a Packet and the data
|
17
|
+
# is invalid.
|
18
|
+
class InvalidPacket < RubySMBError; end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
# Raised when a response packet has a NTStatus code that was unexpected.
|
21
|
+
class UnexpectedStatusCode < RubySMBError; end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
# Raised when an error occurs with the underlying socket.
|
24
|
+
class CommunicationError < RubySMBError; end
|
25
|
+
|
26
|
+
# Raised when Protocol Negotiation fails, possibly due to an
|
27
|
+
# unsupported protocol.
|
28
|
+
class NegotiationFailure < RubySMBError; end
|
29
|
+
end
|
24
30
|
end
|
data/lib/ruby_smb/field.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module RubySMB
|
2
|
+
# Namespace for all of the custom BinData fields used by RubySMB
|
2
3
|
module Field
|
3
4
|
require 'ruby_smb/field/file_time'
|
4
5
|
require 'ruby_smb/field/utime'
|
@@ -8,7 +9,9 @@ module RubySMB
|
|
8
9
|
require 'ruby_smb/field/smb_fea'
|
9
10
|
require 'ruby_smb/field/smb_fea_list'
|
10
11
|
require 'ruby_smb/field/security_descriptor'
|
11
|
-
require 'ruby_smb/field/
|
12
|
-
require 'ruby_smb/field/
|
12
|
+
require 'ruby_smb/field/string16'
|
13
|
+
require 'ruby_smb/field/smb2_fileid'
|
14
|
+
require 'ruby_smb/field/smb_gea'
|
15
|
+
require 'ruby_smb/field/smb_gea_list'
|
13
16
|
end
|
14
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
1
3
|
module RubySMB
|
2
4
|
module Field
|
3
5
|
# Represents a Windows FILETIME structure as defined in
|
@@ -32,7 +34,7 @@ module RubySMB
|
|
32
34
|
time_int *= NS_MULTIPLIER
|
33
35
|
adjusted_epoch = time_int + EPOCH_DIFF_100NS
|
34
36
|
set(adjusted_epoch)
|
35
|
-
when
|
37
|
+
when Integer
|
36
38
|
self.val = value
|
37
39
|
else
|
38
40
|
self.val = value.to_i
|
@@ -4,7 +4,7 @@ module RubySMB
|
|
4
4
|
# [2.4.6 SECURITY_DESCRIPTOR](https://msdn.microsoft.com/en-us/library/cc230366.aspx)
|
5
5
|
class SecurityDescriptor < BinData::Record
|
6
6
|
endian :little
|
7
|
-
uint8 :revision, label: 'Revision',
|
7
|
+
uint8 :revision, label: 'Revision', initial_value: 0x01
|
8
8
|
uint8 :sbz1, label: 'Resource Manager Control Bits'
|
9
9
|
|
10
10
|
struct :control do
|
@@ -28,10 +28,10 @@ module RubySMB
|
|
28
28
|
bit1 :dacl_trusted, label: 'DACL Trusted'
|
29
29
|
end
|
30
30
|
|
31
|
-
uint32 :offset_owner, label: 'Offset Owner', initial_value:
|
32
|
-
uint32 :offset_group, label: 'Offset Group', initial_value:
|
33
|
-
uint32 :offset_sacl, label: 'Offset SACL', initial_value:
|
34
|
-
uint32 :offset_dacl, label: 'Offset DACL', initial_value:
|
31
|
+
uint32 :offset_owner, label: 'Offset Owner', initial_value: -> { owner_sid.rel_offset }
|
32
|
+
uint32 :offset_group, label: 'Offset Group', initial_value: -> { group_sid.rel_offset }
|
33
|
+
uint32 :offset_sacl, label: 'Offset SACL', initial_value: -> { sacl.rel_offset }
|
34
|
+
uint32 :offset_dacl, label: 'Offset DACL', initial_value: -> { dacl.rel_offset }
|
35
35
|
|
36
36
|
string :owner_sid, label: 'Owner SID'
|
37
37
|
string :group_sid, label: 'Group SID'
|
@@ -39,4 +39,4 @@ module RubySMB
|
|
39
39
|
string :dacl, label: 'DACL'
|
40
40
|
end
|
41
41
|
end
|
42
|
-
end
|
42
|
+
end
|