ruby_smb 2.0.2 → 3.0.0
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/.github/workflows/verify.yml +46 -0
- data/README.md +0 -1
- data/examples/anonymous_auth.rb +3 -3
- data/examples/append_file.rb +10 -8
- data/examples/auth_capture.rb +71 -0
- data/examples/authenticate.rb +9 -5
- data/examples/delete_file.rb +8 -6
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/enum_registry_key.rb +5 -4
- data/examples/enum_registry_values.rb +5 -4
- data/examples/get_computer_info.rb +42 -0
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +11 -12
- data/examples/query_service_status.rb +102 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_registry_key_value.rb +6 -5
- data/examples/rename_file.rb +9 -7
- data/examples/tree_connect.rb +7 -5
- data/examples/write_file.rb +9 -7
- data/lib/ruby_smb/client/authentication.rb +5 -10
- data/lib/ruby_smb/client/echo.rb +2 -4
- data/lib/ruby_smb/client/negotiation.rb +13 -16
- data/lib/ruby_smb/client/tree_connect.rb +2 -4
- data/lib/ruby_smb/client/utils.rb +16 -10
- data/lib/ruby_smb/client/winreg.rb +1 -1
- data/lib/ruby_smb/client.rb +102 -75
- data/lib/ruby_smb/compression/lznt1.rb +164 -0
- data/lib/ruby_smb/compression.rb +7 -0
- data/lib/ruby_smb/dcerpc/bind.rb +28 -20
- data/lib/ruby_smb/dcerpc/bind_ack.rb +29 -28
- data/lib/ruby_smb/dcerpc/client.rb +542 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_bind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_request.rb +57 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_crack_names_response.rb +76 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_request.rb +46 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_domain_controller_info_response.rb +168 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_extensions.rb +56 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_request.rb +121 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_get_nc_changes_response.rb +118 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/drsr/drs_unbind_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/drsr.rb +909 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/epm/epm_ept_map_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/epm/epm_twrt.rb +211 -0
- data/lib/ruby_smb/dcerpc/epm.rb +75 -0
- data/lib/ruby_smb/dcerpc/error.rb +20 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +1204 -80
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/netlogon.rb +102 -0
- data/lib/ruby_smb/dcerpc/p_syntax_id_t.rb +4 -3
- data/lib/ruby_smb/dcerpc/pdu_header.rb +7 -7
- data/lib/ruby_smb/dcerpc/ptypes.rb +1 -0
- data/lib/ruby_smb/dcerpc/request.rb +85 -19
- data/lib/ruby_smb/dcerpc/response.rb +45 -10
- data/lib/ruby_smb/dcerpc/rpc_auth3.rb +28 -0
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
- data/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string.rb +118 -0
- data/lib/ruby_smb/dcerpc/samr/rpc_sid.rb +150 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_close_handle_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_request.rb +32 -0
- data/lib/ruby_smb/dcerpc/samr/samr_connect_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response.rb +55 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_alias_membership_response.rb +38 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_get_groups_for_user_response.rb +48 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_domain_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/samr/samr_open_user_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/samr.rb +613 -0
- data/lib/ruby_smb/dcerpc/sec_trailer.rb +26 -0
- data/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all.rb +56 -79
- data/lib/ruby_smb/dcerpc/srvsvc.rb +27 -4
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +36 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +45 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl.rb +477 -0
- data/lib/ruby_smb/dcerpc/uuid.rb +3 -0
- data/lib/ruby_smb/dcerpc/winreg/close_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +62 -0
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +2 -19
- data/lib/ruby_smb/dcerpc/winreg/enum_key_response.rb +3 -20
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +5 -14
- data/lib/ruby_smb/dcerpc/winreg/open_key_request.rb +1 -9
- data/lib/ruby_smb/dcerpc/winreg/open_key_response.rb +4 -3
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +6 -7
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -13
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +7 -15
- data/lib/ruby_smb/dcerpc/winreg/regsam.rb +3 -1
- data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +28 -0
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +99 -22
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response.rb +88 -0
- data/lib/ruby_smb/dcerpc/wkssvc.rb +65 -0
- data/lib/ruby_smb/dcerpc.rb +45 -11
- data/lib/ruby_smb/dialect.rb +45 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/dispatcher/socket.rb +2 -2
- data/lib/ruby_smb/error.rb +21 -5
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/generic_packet.rb +11 -1
- data/lib/ruby_smb/gss/provider/authenticator.rb +42 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +303 -0
- data/lib/ruby_smb/gss/provider.rb +35 -0
- data/lib/ruby_smb/gss.rb +56 -63
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/ntlm.rb +61 -0
- data/lib/ruby_smb/server/server_client/negotiation.rb +156 -0
- data/lib/ruby_smb/server/server_client/session_setup.rb +82 -0
- data/lib/ruby_smb/server/server_client.rb +162 -0
- data/lib/ruby_smb/server.rb +54 -0
- data/lib/ruby_smb/signing.rb +59 -0
- data/lib/ruby_smb/smb1/file.rb +10 -25
- data/lib/ruby_smb/smb1/packet/negotiate_response.rb +11 -11
- data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +1 -1
- data/lib/ruby_smb/smb1/packet/session_setup_request.rb +1 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
- data/lib/ruby_smb/smb1/pipe.rb +12 -6
- data/lib/ruby_smb/smb1/tree.rb +13 -9
- data/lib/ruby_smb/smb2/file.rb +33 -33
- data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
- data/lib/ruby_smb/smb2/packet/compression_transform_header.rb +4 -0
- data/lib/ruby_smb/smb2/packet/negotiate_request.rb +9 -0
- data/lib/ruby_smb/smb2/packet/negotiate_response.rb +0 -1
- data/lib/ruby_smb/smb2/packet/session_setup_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +1 -1
- data/lib/ruby_smb/smb2/pipe.rb +13 -6
- data/lib/ruby_smb/smb2/tree.rb +21 -11
- data/lib/ruby_smb/smb2.rb +3 -1
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +5 -3
- data/spec/lib/ruby_smb/client_spec.rb +199 -86
- data/spec/lib/ruby_smb/compression/lznt1_spec.rb +32 -0
- data/spec/lib/ruby_smb/dcerpc/bind_ack_spec.rb +69 -41
- data/spec/lib/ruby_smb/dcerpc/bind_spec.rb +75 -21
- data/spec/lib/ruby_smb/dcerpc/client_spec.rb +714 -0
- data/spec/lib/ruby_smb/dcerpc/drsr_spec.rb +2169 -0
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +3977 -239
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/p_syntax_id_t_spec.rb +18 -4
- data/spec/lib/ruby_smb/dcerpc/pdu_header_spec.rb +27 -1
- data/spec/lib/ruby_smb/dcerpc/request_spec.rb +76 -11
- data/spec/lib/ruby_smb/dcerpc/response_spec.rb +99 -9
- data/spec/lib/ruby_smb/dcerpc/rpc_auth3_spec.rb +75 -0
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +162 -0
- data/spec/lib/ruby_smb/dcerpc/rrp_rpc_unicode_string_spec.rb +340 -0
- data/spec/lib/ruby_smb/dcerpc/samr/rpc_sid_spec.rb +116 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_close_handle_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_connect_response_spec.rb +47 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_request_spec.rb +63 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_enumerate_users_in_domain_response_spec.rb +265 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_request_spec.rb +52 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_lookup_domain_in_sam_server_response_spec.rb +36 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_request_spec.rb +56 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_open_domain_response_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_request_spec.rb +48 -0
- data/spec/lib/ruby_smb/dcerpc/samr/samr_rid_to_sid_response_spec.rb +42 -0
- data/spec/lib/ruby_smb/dcerpc/samr_spec.rb +420 -0
- data/spec/lib/ruby_smb/dcerpc/sec_trailer_spec.rb +92 -0
- data/spec/lib/ruby_smb/dcerpc/srvsvc/net_share_enum_all_spec.rb +149 -110
- data/spec/lib/ruby_smb/dcerpc/srvsvc_spec.rb +21 -17
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +168 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +68 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +76 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +47 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +508 -0
- data/spec/lib/ruby_smb/dcerpc/uuid_spec.rb +15 -23
- data/spec/lib/ruby_smb/dcerpc/winreg/close_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +73 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -56
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_response_spec.rb +4 -56
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +10 -34
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_request_spec.rb +2 -26
- data/spec/lib/ruby_smb/dcerpc/winreg/open_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +17 -20
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_response_spec.rb +20 -44
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +8 -32
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +18 -42
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +219 -62
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_request_spec.rb +43 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc/netr_wksta_get_info_response_spec.rb +410 -0
- data/spec/lib/ruby_smb/dcerpc/wkssvc_spec.rb +70 -0
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
- data/spec/lib/ruby_smb/error_spec.rb +34 -5
- data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/account_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +101 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +32 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm_spec.rb +113 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/server/server_client_spec.rb +156 -0
- data/spec/lib/ruby_smb/server_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +20 -14
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +20 -14
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +0 -0
- metadata +229 -23
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -6
- data/lib/ruby_smb/client/signing.rb +0 -64
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -35
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -98
|
@@ -65,6 +65,8 @@ RSpec.describe RubySMB::Client do
|
|
|
65
65
|
it { is_expected.to respond_to :verify_signature }
|
|
66
66
|
it { is_expected.to respond_to :auth_user }
|
|
67
67
|
it { is_expected.to respond_to :last_file_id }
|
|
68
|
+
it { is_expected.to respond_to :pid }
|
|
69
|
+
it { is_expected.to respond_to :server_supports_multi_credit }
|
|
68
70
|
|
|
69
71
|
describe '#initialize' do
|
|
70
72
|
it 'should raise an ArgumentError without a valid dispatcher' do
|
|
@@ -124,8 +126,7 @@ RSpec.describe RubySMB::Client do
|
|
|
124
126
|
expect(password).to eq(password)
|
|
125
127
|
expect(opt[:workstation]).to eq(local_workstation)
|
|
126
128
|
expect(opt[:domain]).to eq(domain)
|
|
127
|
-
flags =
|
|
128
|
-
Net::NTLM::FLAGS[:TARGET_INFO] | 0x02000000 ^ Net::NTLM::FLAGS[:OEM]
|
|
129
|
+
flags = RubySMB::NTLM::DEFAULT_CLIENT_FLAGS
|
|
129
130
|
expect(opt[:flags]).to eq(flags)
|
|
130
131
|
end
|
|
131
132
|
|
|
@@ -141,6 +142,18 @@ RSpec.describe RubySMB::Client do
|
|
|
141
142
|
it 'sets the max_buffer_size to MAX_BUFFER_SIZE' do
|
|
142
143
|
expect(client.max_buffer_size).to eq RubySMB::Client::MAX_BUFFER_SIZE
|
|
143
144
|
end
|
|
145
|
+
|
|
146
|
+
it 'sets the server_supports_multi_credit to false' do
|
|
147
|
+
expect(client.server_supports_multi_credit).to be false
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'sets the pid to a random value' do
|
|
151
|
+
100.times do
|
|
152
|
+
previous_pid = client.pid
|
|
153
|
+
client = described_class.new(dispatcher, username: username, password: password)
|
|
154
|
+
expect(client.pid).to_not eq(previous_pid)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
144
157
|
end
|
|
145
158
|
|
|
146
159
|
describe '#echo' do
|
|
@@ -184,37 +197,38 @@ RSpec.describe RubySMB::Client do
|
|
|
184
197
|
describe '#send_recv' do
|
|
185
198
|
let(:smb1_request) { RubySMB::SMB1::Packet::TreeConnectRequest.new }
|
|
186
199
|
let(:smb2_request) { RubySMB::SMB2::Packet::TreeConnectRequest.new }
|
|
200
|
+
let(:smb2_header) { RubySMB::SMB2::SMB2Header.new }
|
|
187
201
|
|
|
188
202
|
before(:each) do
|
|
189
203
|
allow(client).to receive(:is_status_pending?).and_return(false)
|
|
190
204
|
allow(dispatcher).to receive(:send_packet).and_return(nil)
|
|
191
205
|
allow(dispatcher).to receive(:recv_packet).and_return('A')
|
|
206
|
+
allow(RubySMB::SMB2::SMB2Header).to receive(:read).and_return(smb2_header)
|
|
192
207
|
end
|
|
193
208
|
|
|
194
209
|
context 'when signing' do
|
|
195
210
|
it 'calls #smb1_sign if it is an SMB1 packet' do
|
|
211
|
+
allow(client).to receive(:signing_required).and_return(true)
|
|
212
|
+
allow(client).to receive(:session_key).and_return(Random.new.bytes(16))
|
|
196
213
|
expect(client).to receive(:smb1_sign).with(smb1_request).and_call_original
|
|
197
214
|
client.send_recv(smb1_request)
|
|
198
215
|
end
|
|
199
216
|
|
|
200
217
|
context 'with an SMB2 packet' do
|
|
201
218
|
it 'does not sign a SessionSetupRequest packet' do
|
|
219
|
+
allow(smb2_client).to receive(:is_status_pending?).and_return(false)
|
|
202
220
|
expect(smb2_client).to_not receive(:smb2_sign)
|
|
203
221
|
expect(smb2_client).to_not receive(:smb3_sign)
|
|
204
|
-
|
|
222
|
+
smb2_client.send_recv(RubySMB::SMB2::Packet::SessionSetupRequest.new)
|
|
205
223
|
end
|
|
206
224
|
|
|
207
225
|
it 'calls #smb2_sign if it is an SMB2 client' do
|
|
208
226
|
allow(smb2_client).to receive(:is_status_pending?).and_return(false)
|
|
227
|
+
allow(smb2_client).to receive(:signing_required).and_return(true)
|
|
228
|
+
allow(smb2_client).to receive(:session_key).and_return(Random.new.bytes(16))
|
|
209
229
|
expect(smb2_client).to receive(:smb2_sign).with(smb2_request).and_call_original
|
|
210
230
|
smb2_client.send_recv(smb2_request)
|
|
211
231
|
end
|
|
212
|
-
|
|
213
|
-
it 'calls #smb3_sign if it is an SMB3 client' do
|
|
214
|
-
allow(smb3_client).to receive(:is_status_pending?).and_return(false)
|
|
215
|
-
expect(smb3_client).to receive(:smb3_sign).with(smb2_request).and_call_original
|
|
216
|
-
smb3_client.send_recv(smb2_request)
|
|
217
|
-
end
|
|
218
232
|
end
|
|
219
233
|
end
|
|
220
234
|
|
|
@@ -229,6 +243,29 @@ RSpec.describe RubySMB::Client do
|
|
|
229
243
|
expect(smb1_client).to_not receive(:is_status_pending?)
|
|
230
244
|
smb1_client.send_recv(smb1_request)
|
|
231
245
|
end
|
|
246
|
+
|
|
247
|
+
it 'set the #uid SMB header when #user_id is defined' do
|
|
248
|
+
smb1_client.user_id = 333
|
|
249
|
+
smb1_client.send_recv(smb1_request)
|
|
250
|
+
expect(smb1_request.smb_header.uid).to eq(333)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it 'does not set the #uid SMB header when #user_id is not defined' do
|
|
254
|
+
smb1_client.send_recv(smb1_request)
|
|
255
|
+
expect(smb1_request.smb_header.uid).to eq(0)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'set the #pid SMB header when #pid is defined' do
|
|
259
|
+
smb1_client.pid = 333
|
|
260
|
+
smb1_client.send_recv(smb1_request)
|
|
261
|
+
expect(smb1_request.smb_header.pid_low).to eq(333)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'does not set the #pid SMB header when #pid is not defined' do
|
|
265
|
+
smb1_client.pid = nil
|
|
266
|
+
smb1_client.send_recv(smb1_request)
|
|
267
|
+
expect(smb1_request.smb_header.pid_low).to eq(0)
|
|
268
|
+
end
|
|
232
269
|
end
|
|
233
270
|
|
|
234
271
|
context 'with SMB2' do
|
|
@@ -251,10 +288,8 @@ RSpec.describe RubySMB::Client do
|
|
|
251
288
|
context 'with a SessionSetupRequest' do
|
|
252
289
|
it 'does not encrypt/decrypt' do
|
|
253
290
|
request = RubySMB::SMB2::Packet::SessionSetupRequest.new
|
|
254
|
-
expect(smb3_client).
|
|
255
|
-
expect(smb3_client).
|
|
256
|
-
expect(dispatcher).to receive(:send_packet).with(request)
|
|
257
|
-
expect(dispatcher).to receive(:recv_packet)
|
|
291
|
+
expect(smb3_client).to receive(:send_packet).with(request, encrypt: false)
|
|
292
|
+
expect(smb3_client).to receive(:recv_packet).with(encrypt: false)
|
|
258
293
|
smb3_client.send_recv(request)
|
|
259
294
|
end
|
|
260
295
|
end
|
|
@@ -262,17 +297,15 @@ RSpec.describe RubySMB::Client do
|
|
|
262
297
|
context 'with a NegotiateRequest' do
|
|
263
298
|
it 'does not encrypt/decrypt' do
|
|
264
299
|
request = RubySMB::SMB2::Packet::NegotiateRequest.new
|
|
265
|
-
expect(smb3_client).
|
|
266
|
-
expect(smb3_client).
|
|
267
|
-
expect(dispatcher).to receive(:send_packet).with(request)
|
|
268
|
-
expect(dispatcher).to receive(:recv_packet)
|
|
300
|
+
expect(smb3_client).to receive(:send_packet).with(request, encrypt: false)
|
|
301
|
+
expect(smb3_client).to receive(:recv_packet).with(encrypt: false)
|
|
269
302
|
smb3_client.send_recv(request)
|
|
270
303
|
end
|
|
271
304
|
end
|
|
272
305
|
|
|
273
306
|
it 'encrypts and decrypts' do
|
|
274
|
-
expect(smb3_client).to receive(:
|
|
275
|
-
expect(smb3_client).to receive(:
|
|
307
|
+
expect(smb3_client).to receive(:send_packet).with(smb2_request, encrypt: true)
|
|
308
|
+
expect(smb3_client).to receive(:recv_packet).with(encrypt: true)
|
|
276
309
|
smb3_client.send_recv(smb2_request)
|
|
277
310
|
end
|
|
278
311
|
|
|
@@ -280,12 +313,44 @@ RSpec.describe RubySMB::Client do
|
|
|
280
313
|
it 'waits 1 second and reads/decrypts again' do
|
|
281
314
|
allow(smb3_client).to receive(:is_status_pending?).and_return(true, false)
|
|
282
315
|
expect(smb3_client).to receive(:sleep).with(1)
|
|
283
|
-
expect(smb3_client).to receive(:
|
|
284
|
-
expect(smb3_client).to receive(:
|
|
316
|
+
expect(smb3_client).to receive(:send_packet).with(smb2_request, encrypt: true)
|
|
317
|
+
expect(smb3_client).to receive(:recv_packet).with(encrypt: true).twice
|
|
285
318
|
smb3_client.send_recv(smb2_request)
|
|
286
319
|
end
|
|
287
320
|
end
|
|
288
321
|
end
|
|
322
|
+
|
|
323
|
+
it 'increments the sequence counter if signing is required and the session key exist' do
|
|
324
|
+
allow(smb2_client).to receive(:is_status_pending?).and_return(false)
|
|
325
|
+
smb2_client.signing_required = true
|
|
326
|
+
smb2_client.session_key = 'key'
|
|
327
|
+
smb2_client.sequence_counter = 0
|
|
328
|
+
smb2_client.send_recv(smb2_request)
|
|
329
|
+
expect(smb2_client.sequence_counter).to eq(1)
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
it 'updates #smb2_message_id with SMB2 header #credit_charge if the server supports multi credits' do
|
|
333
|
+
allow(smb2_client).to receive(:is_status_pending?).and_return(false)
|
|
334
|
+
smb2_client.smb2_message_id = 0
|
|
335
|
+
smb2_client.server_supports_multi_credit = true
|
|
336
|
+
smb2_header.credit_charge = 5
|
|
337
|
+
smb2_client.send_recv(smb2_request)
|
|
338
|
+
expect(smb2_client.smb2_message_id).to eq(5)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it 'does not update #msb2_message_id with SMB2 header #credit_charge if the server does not support multi credits' do
|
|
342
|
+
allow(smb2_client).to receive(:is_status_pending?).and_return(false)
|
|
343
|
+
smb2_client.smb2_message_id = 0
|
|
344
|
+
smb2_client.server_supports_multi_credit = false
|
|
345
|
+
smb2_header.credit_charge = 5
|
|
346
|
+
smb2_client.send_recv(smb2_request)
|
|
347
|
+
expect(smb2_client.smb2_message_id).to eq(1)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'ignores errors thrown when parsing the SMB2 header' do
|
|
351
|
+
allow(RubySMB::SMB2::SMB2Header).to receive(:read).and_raise(IOError)
|
|
352
|
+
expect { smb2_client.send_recv(smb2_request) }.to_not raise_error
|
|
353
|
+
end
|
|
289
354
|
end
|
|
290
355
|
|
|
291
356
|
describe '#is_status_pending?' do
|
|
@@ -297,17 +362,17 @@ RSpec.describe RubySMB::Client do
|
|
|
297
362
|
}
|
|
298
363
|
|
|
299
364
|
it 'returns true when the response has a STATUS_PENDING status code and the async_command flag set' do
|
|
300
|
-
expect(client.is_status_pending?(response.
|
|
365
|
+
expect(client.is_status_pending?(response.smb2_header)).to be true
|
|
301
366
|
end
|
|
302
367
|
|
|
303
368
|
it 'returns false when the response has a STATUS_PENDING status code and the async_command flag not set' do
|
|
304
369
|
response.smb2_header.flags.async_command = 0
|
|
305
|
-
expect(client.is_status_pending?(response.
|
|
370
|
+
expect(client.is_status_pending?(response.smb2_header)).to be false
|
|
306
371
|
end
|
|
307
372
|
|
|
308
373
|
it 'returns false when the response has no STATUS_PENDING status code but the async_command flag set' do
|
|
309
374
|
response.smb2_header.nt_status= WindowsError::NTStatus::STATUS_SUCCESS.value
|
|
310
|
-
expect(client.is_status_pending?(response.
|
|
375
|
+
expect(client.is_status_pending?(response.smb2_header)).to be false
|
|
311
376
|
end
|
|
312
377
|
end
|
|
313
378
|
|
|
@@ -344,35 +409,47 @@ RSpec.describe RubySMB::Client do
|
|
|
344
409
|
end
|
|
345
410
|
end
|
|
346
411
|
|
|
347
|
-
describe '#
|
|
412
|
+
describe '#send_packet' do
|
|
348
413
|
let(:packet) { RubySMB::SMB2::Packet::SessionSetupRequest.new }
|
|
349
414
|
before :example do
|
|
350
415
|
allow(dispatcher).to receive(:send_packet)
|
|
351
416
|
client.dialect = '0x0300'
|
|
352
417
|
end
|
|
353
418
|
|
|
354
|
-
it '
|
|
355
|
-
expect(client).
|
|
356
|
-
client.
|
|
419
|
+
it 'does not encrypt the packet' do
|
|
420
|
+
expect(client).to_not receive(:smb3_encrypt)
|
|
421
|
+
client.send_packet(packet)
|
|
357
422
|
end
|
|
358
423
|
|
|
359
|
-
it '
|
|
360
|
-
|
|
361
|
-
expect
|
|
362
|
-
RubySMB::Error::EncryptionError,
|
|
363
|
-
"Error while encrypting #{packet.class.name} packet (SMB 0x0300): Error"
|
|
364
|
-
)
|
|
424
|
+
it 'sends the packet through the dispatcher' do
|
|
425
|
+
client.send_packet(packet)
|
|
426
|
+
expect(dispatcher).to have_received(:send_packet).with(packet)
|
|
365
427
|
end
|
|
366
428
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
429
|
+
context 'with encryption' do
|
|
430
|
+
it 'creates a Transform request' do
|
|
431
|
+
expect(client).to receive(:smb3_encrypt).with(packet.to_binary_s)
|
|
432
|
+
client.send_packet(packet, encrypt: true)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
it 'raises an EncryptionError exception if an error occurs while encrypting' do
|
|
436
|
+
allow(client).to receive(:smb3_encrypt).and_raise(RubySMB::Error::RubySMBError.new('Error'))
|
|
437
|
+
expect { client.send_packet(packet, encrypt: true) }.to raise_error(
|
|
438
|
+
RubySMB::Error::EncryptionError,
|
|
439
|
+
"Error while encrypting #{packet.class.name} packet (SMB 0x0300): Error"
|
|
440
|
+
)
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
it 'sends the encrypted packet' do
|
|
444
|
+
encrypted_packet = double('Encrypted packet')
|
|
445
|
+
allow(client).to receive(:smb3_encrypt).and_return(encrypted_packet)
|
|
446
|
+
client.send_packet(packet, encrypt: true)
|
|
447
|
+
expect(dispatcher).to have_received(:send_packet).with(encrypted_packet)
|
|
448
|
+
end
|
|
372
449
|
end
|
|
373
450
|
end
|
|
374
451
|
|
|
375
|
-
describe '#
|
|
452
|
+
describe '#recv_packet' do
|
|
376
453
|
let(:packet) { RubySMB::SMB2::Packet::SessionSetupRequest.new }
|
|
377
454
|
before :example do
|
|
378
455
|
allow(dispatcher).to receive(:recv_packet).and_return(packet.to_binary_s)
|
|
@@ -381,42 +458,49 @@ RSpec.describe RubySMB::Client do
|
|
|
381
458
|
end
|
|
382
459
|
|
|
383
460
|
it 'reads the response packet' do
|
|
384
|
-
client.
|
|
461
|
+
client.recv_packet
|
|
385
462
|
expect(dispatcher).to have_received(:recv_packet)
|
|
386
463
|
end
|
|
387
464
|
|
|
388
|
-
it 'raises an
|
|
465
|
+
it 'raises an CommunicationError exception if an error occurs while receiving the response' do
|
|
389
466
|
allow(dispatcher).to receive(:recv_packet).and_raise(RubySMB::Error::CommunicationError)
|
|
390
|
-
expect { client.
|
|
391
|
-
RubySMB::Error::EncryptionError,
|
|
392
|
-
'Communication error with the remote host: RubySMB::Error::CommunicationError. '\
|
|
393
|
-
'The server supports encryption but was not able to handle the encrypted request.'
|
|
394
|
-
)
|
|
467
|
+
expect { client.recv_packet }.to raise_error(RubySMB::Error::CommunicationError)
|
|
395
468
|
end
|
|
396
469
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
470
|
+
context 'with encryption' do
|
|
471
|
+
it 'raises an EncryptionError exception if an error occurs while receiving the response' do
|
|
472
|
+
allow(dispatcher).to receive(:recv_packet).and_raise(RubySMB::Error::CommunicationError)
|
|
473
|
+
expect { client.recv_packet(encrypt: true) }.to raise_error(
|
|
474
|
+
RubySMB::Error::EncryptionError,
|
|
475
|
+
'Communication error with the remote host: RubySMB::Error::CommunicationError. '\
|
|
476
|
+
'The server supports encryption but was not able to handle the encrypted request.'
|
|
477
|
+
)
|
|
478
|
+
end
|
|
401
479
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
480
|
+
it 'parses the response as a Transform response packet' do
|
|
481
|
+
expect(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).with(packet.to_binary_s)
|
|
482
|
+
client.recv_packet(encrypt: true)
|
|
483
|
+
end
|
|
406
484
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
expect(client).to have_received(:smb3_decrypt).with(transform)
|
|
412
|
-
end
|
|
485
|
+
it 'raises an InvalidPacket exception if an error occurs while parsing the response' do
|
|
486
|
+
allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_raise(IOError)
|
|
487
|
+
expect { client.recv_packet(encrypt: true) }.to raise_error(RubySMB::Error::InvalidPacket, 'Not a SMB2 TransformHeader packet')
|
|
488
|
+
end
|
|
413
489
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
490
|
+
it 'decrypts the Transform response packet' do
|
|
491
|
+
transform = double('Transform header packet')
|
|
492
|
+
allow(RubySMB::SMB2::Packet::TransformHeader).to receive(:read).and_return(transform)
|
|
493
|
+
client.recv_packet(encrypt: true)
|
|
494
|
+
expect(client).to have_received(:smb3_decrypt).with(transform)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
it 'raises an EncryptionError exception if an error occurs while decrypting' do
|
|
498
|
+
allow(client).to receive(:smb3_decrypt).and_raise(RubySMB::Error::RubySMBError)
|
|
499
|
+
expect { client.recv_packet(encrypt: true) }.to raise_error(
|
|
500
|
+
RubySMB::Error::EncryptionError,
|
|
501
|
+
'Error while decrypting RubySMB::SMB2::Packet::TransformHeader packet (SMB 0x0300}): RubySMB::Error::RubySMBError'
|
|
502
|
+
)
|
|
503
|
+
end
|
|
420
504
|
end
|
|
421
505
|
end
|
|
422
506
|
|
|
@@ -667,7 +751,7 @@ RSpec.describe RubySMB::Client do
|
|
|
667
751
|
expect(session_packet.session_header.session_packet_type).to eq RubySMB::Nbss::SESSION_REQUEST
|
|
668
752
|
expect(session_packet.called_name).to eq called_name
|
|
669
753
|
expect(session_packet.calling_name).to eq calling_name
|
|
670
|
-
expect(session_packet.session_header.
|
|
754
|
+
expect(session_packet.session_header.stream_protocol_length).to eq(
|
|
671
755
|
session_packet.called_name.to_binary_s.size + session_packet.calling_name.to_binary_s.size
|
|
672
756
|
)
|
|
673
757
|
end
|
|
@@ -722,6 +806,18 @@ RSpec.describe RubySMB::Client do
|
|
|
722
806
|
smb1_extended_response.to_binary_s
|
|
723
807
|
}
|
|
724
808
|
|
|
809
|
+
let(:smb1_response) {
|
|
810
|
+
packet = RubySMB::SMB1::Packet::NegotiateResponse.new
|
|
811
|
+
smb1_capabilities_dup = smb1_capabilities.dup
|
|
812
|
+
smb1_capabilities_dup[:extended_security] = 0
|
|
813
|
+
|
|
814
|
+
packet.parameter_block.capabilities = smb1_capabilities_dup
|
|
815
|
+
packet
|
|
816
|
+
}
|
|
817
|
+
let(:smb1_response_raw) {
|
|
818
|
+
smb1_response.to_binary_s
|
|
819
|
+
}
|
|
820
|
+
|
|
725
821
|
let(:smb2_response) { RubySMB::SMB2::Packet::NegotiateResponse.new(dialect_revision: 0x200) }
|
|
726
822
|
let(:smb3_response) { RubySMB::SMB2::Packet::NegotiateResponse.new(dialect_revision: 0x300) }
|
|
727
823
|
|
|
@@ -910,10 +1006,14 @@ RSpec.describe RubySMB::Client do
|
|
|
910
1006
|
|
|
911
1007
|
describe '#negotiate_response' do
|
|
912
1008
|
context 'with only SMB1' do
|
|
913
|
-
it 'returns a properly formed packet' do
|
|
1009
|
+
it 'returns a properly formed NegotiateResponseExtended packet if extended_security is set as 1' do
|
|
914
1010
|
expect(smb1_client.negotiate_response(smb1_extended_response_raw)).to eq smb1_extended_response
|
|
915
1011
|
end
|
|
916
1012
|
|
|
1013
|
+
it 'returns a properly formed NegotiateResponse packet if extended_security is set as 0' do
|
|
1014
|
+
expect(smb1_client.negotiate_response(smb1_response_raw)).to eq smb1_response
|
|
1015
|
+
end
|
|
1016
|
+
|
|
917
1017
|
it 'raises an exception if the response is not a SMB packet' do
|
|
918
1018
|
expect { smb1_client.negotiate_response(random_junk) }.to raise_error(RubySMB::Error::InvalidPacket)
|
|
919
1019
|
end
|
|
@@ -928,12 +1028,6 @@ RSpec.describe RubySMB::Client do
|
|
|
928
1028
|
bogus_response.smb_header.command = 0xff
|
|
929
1029
|
expect { smb1_client.negotiate_response(bogus_response.to_binary_s) }.to raise_error(RubySMB::Error::InvalidPacket)
|
|
930
1030
|
end
|
|
931
|
-
|
|
932
|
-
it 'considers the response invalid if Extended Security is not enabled' do
|
|
933
|
-
bogus_response = smb1_extended_response
|
|
934
|
-
bogus_response.parameter_block.capabilities.extended_security = 0
|
|
935
|
-
expect { smb1_client.negotiate_response(bogus_response.to_binary_s) }.to raise_error(RubySMB::Error::InvalidPacket)
|
|
936
|
-
end
|
|
937
1031
|
end
|
|
938
1032
|
|
|
939
1033
|
context 'with only SMB2' do
|
|
@@ -1036,6 +1130,19 @@ RSpec.describe RubySMB::Client do
|
|
|
1036
1130
|
it 'returns the string \'SMB2\'' do
|
|
1037
1131
|
expect(client.parse_negotiate_response(smb2_response)).to eq ('SMB2')
|
|
1038
1132
|
end
|
|
1133
|
+
|
|
1134
|
+
it 'sets #server_supports_multi_credit to true when the response has #large_mtu capability set' do
|
|
1135
|
+
smb2_response.capabilities.large_mtu = 1
|
|
1136
|
+
client.parse_negotiate_response(smb2_response)
|
|
1137
|
+
expect(client.server_supports_multi_credit).to be true
|
|
1138
|
+
end
|
|
1139
|
+
|
|
1140
|
+
it 'sets #server_supports_multi_credit to false when the dialect is 0x0202' do
|
|
1141
|
+
smb2_response.dialect_revision = 0x0202
|
|
1142
|
+
smb2_response.capabilities.large_mtu = 1 # just to make sure it won't affect the result
|
|
1143
|
+
client.parse_negotiate_response(smb2_response)
|
|
1144
|
+
expect(client.server_supports_multi_credit).to be false
|
|
1145
|
+
end
|
|
1039
1146
|
end
|
|
1040
1147
|
|
|
1041
1148
|
context 'when SMB3 was negotiated' do
|
|
@@ -1060,6 +1167,12 @@ RSpec.describe RubySMB::Client do
|
|
|
1060
1167
|
expect(client.parse_negotiate_response(smb3_response)).to eq ('SMB3')
|
|
1061
1168
|
end
|
|
1062
1169
|
|
|
1170
|
+
it 'sets #server_supports_multi_credit to true when the response has #large_mtu capability set' do
|
|
1171
|
+
smb3_response.capabilities.large_mtu = 1
|
|
1172
|
+
client.parse_negotiate_response(smb3_response)
|
|
1173
|
+
expect(client.server_supports_multi_credit).to be true
|
|
1174
|
+
end
|
|
1175
|
+
|
|
1063
1176
|
context 'when the server supports encryption' do
|
|
1064
1177
|
before :example do
|
|
1065
1178
|
smb3_response.capabilities.encryption = 1
|
|
@@ -1971,7 +2084,7 @@ RSpec.describe RubySMB::Client do
|
|
|
1971
2084
|
it 'generates the HMAC based on the packet and the NTLM session key and signs the packet with it' do
|
|
1972
2085
|
smb2_client.session_key = 'foo'
|
|
1973
2086
|
smb2_client.signing_required = true
|
|
1974
|
-
expect(OpenSSL::HMAC).to receive(:digest).with(instance_of(OpenSSL::Digest
|
|
2087
|
+
expect(OpenSSL::HMAC).to receive(:digest).with(instance_of(OpenSSL::Digest), smb2_client.session_key, request1.to_binary_s).and_return(fake_hmac)
|
|
1975
2088
|
expect(smb2_client.smb2_sign(request1).smb2_header.signature).to eq fake_hmac
|
|
1976
2089
|
end
|
|
1977
2090
|
end
|
|
@@ -2071,7 +2184,7 @@ RSpec.describe RubySMB::Client do
|
|
|
2071
2184
|
smb3_client.dialect = '0x0202'
|
|
2072
2185
|
expect { smb3_client.smb3_sign(request) }.to raise_error(
|
|
2073
2186
|
RubySMB::Error::SigningError,
|
|
2074
|
-
'Dialect is incompatible with SMBv3 signing'
|
|
2187
|
+
'Dialect "0x0202" is incompatible with SMBv3 signing'
|
|
2075
2188
|
)
|
|
2076
2189
|
end
|
|
2077
2190
|
end
|
|
@@ -2121,7 +2234,7 @@ RSpec.describe RubySMB::Client do
|
|
|
2121
2234
|
smb3_client.dialect = '0x0202'
|
|
2122
2235
|
expect { smb3_client.smb3_sign(request) }.to raise_error(
|
|
2123
2236
|
RubySMB::Error::SigningError,
|
|
2124
|
-
'Dialect is incompatible with SMBv3 signing'
|
|
2237
|
+
'Dialect "0x0202" is incompatible with SMBv3 signing'
|
|
2125
2238
|
)
|
|
2126
2239
|
end
|
|
2127
2240
|
end
|
|
@@ -2253,7 +2366,7 @@ RSpec.describe RubySMB::Client do
|
|
|
2253
2366
|
let(:named_pipe){ double("Named Pipe") }
|
|
2254
2367
|
|
|
2255
2368
|
before :example do
|
|
2256
|
-
allow(tree).to receive(:
|
|
2369
|
+
allow(tree).to receive(:open_pipe).and_return(named_pipe)
|
|
2257
2370
|
allow(named_pipe).to receive(:net_share_enum_all)
|
|
2258
2371
|
end
|
|
2259
2372
|
|
|
@@ -2268,8 +2381,8 @@ RSpec.describe RubySMB::Client do
|
|
|
2268
2381
|
smb1_client.net_share_enum_all(sock.peeraddr)
|
|
2269
2382
|
end
|
|
2270
2383
|
|
|
2271
|
-
it 'it calls the Tree #
|
|
2272
|
-
expect(tree).to receive(:
|
|
2384
|
+
it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
|
|
2385
|
+
expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
|
|
2273
2386
|
smb1_client.net_share_enum_all(sock.peeraddr)
|
|
2274
2387
|
end
|
|
2275
2388
|
|
|
@@ -2291,8 +2404,8 @@ RSpec.describe RubySMB::Client do
|
|
|
2291
2404
|
smb2_client.net_share_enum_all(sock.peeraddr)
|
|
2292
2405
|
end
|
|
2293
2406
|
|
|
2294
|
-
it 'it calls the Tree #
|
|
2295
|
-
expect(tree).to receive(:
|
|
2407
|
+
it 'it calls the Tree #open_pipe method to open "srvsvc" named pipe' do
|
|
2408
|
+
expect(tree).to receive(:open_pipe).with(filename: "srvsvc", write: true, read: true).and_return(named_pipe)
|
|
2296
2409
|
smb2_client.net_share_enum_all(sock.peeraddr)
|
|
2297
2410
|
end
|
|
2298
2411
|
|
|
@@ -2373,7 +2486,7 @@ RSpec.describe RubySMB::Client do
|
|
|
2373
2486
|
before :example do
|
|
2374
2487
|
allow(ipc_tree).to receive_messages(
|
|
2375
2488
|
:share => share,
|
|
2376
|
-
:
|
|
2489
|
+
:open_pipe => named_pipe
|
|
2377
2490
|
)
|
|
2378
2491
|
allow(client).to receive(:tree_connect).and_return(ipc_tree)
|
|
2379
2492
|
end
|
|
@@ -2395,9 +2508,9 @@ RSpec.describe RubySMB::Client do
|
|
|
2395
2508
|
expect(client).to have_received(:tree_connect).with(share)
|
|
2396
2509
|
end
|
|
2397
2510
|
|
|
2398
|
-
it 'open \'winreg\'
|
|
2511
|
+
it 'open \'winreg\' pipe on the IPC$ Tree' do
|
|
2399
2512
|
client.connect_to_winreg(host)
|
|
2400
|
-
expect(ipc_tree).to have_received(:
|
|
2513
|
+
expect(ipc_tree).to have_received(:open_pipe).with(filename: "winreg", write: true, read: true)
|
|
2401
2514
|
end
|
|
2402
2515
|
|
|
2403
2516
|
it 'returns the expected opened named pipe' do
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RubySMB::Compression::LZNT1 do
|
|
4
|
+
describe '.compress' do
|
|
5
|
+
it 'generates an empty blob when provided an empty blob' do
|
|
6
|
+
expected = "".b
|
|
7
|
+
expect(described_class.compress('')).to eq(expected)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'generates a compressed blob when provided a string with non-reoccurring characters' do
|
|
11
|
+
expect(described_class.compress('RubySMB')).to eq("\x060RubySMB".b)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'generates a compressed blob when provided a string of reoccurring characters' do
|
|
15
|
+
expect(described_class.compress("\x01" * 0x200)).to eq("\x03\xB0\x02\x01\xFC\x01".b)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '.decompress' do
|
|
20
|
+
it 'generates a decompressed blob for a string with non-reoccurring characters' do
|
|
21
|
+
expect(described_class.decompress("\x060RubySMB".b)).to eq('RubySMB')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'generates a decompressed blob for a string of reoccurring characters' do
|
|
25
|
+
expect(described_class.decompress("\x03\xB0\x02\x01\xFC\x01".b)).to eq("\x01" * 0x200)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'raises an EncodingError when the length is invalid' do
|
|
29
|
+
expect { described_class.decompress("\x010".b) }.to raise_error(EncodingError)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|