ruby_smb 2.0.11 → 3.0.1
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 +5 -16
- data/examples/auth_capture.rb +28 -0
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/file_server.rb +76 -0
- data/examples/get_computer_info.rb +42 -0
- data/examples/query_service_status.rb +42 -4
- data/lib/ruby_smb/client.rb +3 -14
- data/lib/ruby_smb/create_actions.rb +21 -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 +17 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +1159 -297
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +3 -13
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/netlogon.rb +5 -4
- 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 +79 -32
- 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 +11 -11
- 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 +13 -25
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +4 -14
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +3 -11
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +12 -11
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +9 -8
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +3 -3
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/svcctl.rb +1 -3
- 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 +2 -13
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +3 -3
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +3 -20
- 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 +5 -6
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_response.rb +2 -2
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_response.rb +9 -18
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +4 -14
- 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 +0 -9
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg.rb +10 -14
- 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 +41 -11
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/nt_status.rb +20 -1
- data/lib/ruby_smb/field/string16.rb +5 -1
- data/lib/ruby_smb/fscc/file_information/file_ea_information.rb +14 -0
- data/lib/ruby_smb/fscc/file_information/file_network_open_information.rb +22 -0
- data/lib/ruby_smb/fscc/file_information/file_stream_information.rb +16 -0
- data/lib/ruby_smb/fscc/file_information.rb +29 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_attribute_information.rb +46 -0
- data/lib/ruby_smb/fscc/file_system_information/file_fs_volume_information.rb +19 -0
- data/lib/ruby_smb/fscc/file_system_information.rb +22 -0
- data/lib/ruby_smb/fscc.rb +1 -0
- data/lib/ruby_smb/generic_packet.rb +6 -0
- data/lib/ruby_smb/gss/provider/authenticator.rb +4 -0
- data/lib/ruby_smb/gss/provider/ntlm.rb +13 -3
- data/lib/ruby_smb/ntlm.rb +18 -2
- data/lib/ruby_smb/server/server_client/negotiation.rb +1 -2
- data/lib/ruby_smb/server/server_client/session_setup.rb +44 -33
- data/lib/ruby_smb/server/server_client/share_io.rb +28 -0
- data/lib/ruby_smb/server/server_client/tree_connect.rb +60 -0
- data/lib/ruby_smb/server/server_client.rb +214 -25
- data/lib/ruby_smb/server/session.rb +71 -0
- data/lib/ruby_smb/server/share/provider/disk.rb +437 -0
- data/lib/ruby_smb/server/share/provider/pipe.rb +27 -0
- data/lib/ruby_smb/server/share/provider/processor.rb +76 -0
- data/lib/ruby_smb/server/share/provider.rb +38 -0
- data/lib/ruby_smb/server/share.rb +11 -0
- data/lib/ruby_smb/server.rb +35 -3
- data/lib/ruby_smb/signing.rb +37 -11
- data/lib/ruby_smb/smb1/commands.rb +4 -0
- data/lib/ruby_smb/smb1/pipe.rb +4 -0
- data/lib/ruby_smb/smb1.rb +0 -1
- data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +2 -1
- data/lib/ruby_smb/smb2/commands.rb +4 -0
- data/lib/ruby_smb/smb2/create_context/request.rb +64 -0
- data/lib/ruby_smb/smb2/create_context/response.rb +62 -0
- data/lib/ruby_smb/smb2/create_context.rb +74 -22
- data/lib/ruby_smb/smb2/packet/create_request.rb +44 -11
- data/lib/ruby_smb/smb2/packet/create_response.rb +17 -3
- data/lib/ruby_smb/smb2/packet/query_directory_request.rb +1 -1
- data/lib/ruby_smb/smb2/packet/query_directory_response.rb +2 -2
- data/lib/ruby_smb/smb2/packet/query_info_request.rb +43 -0
- data/lib/ruby_smb/smb2/packet/query_info_response.rb +23 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +1 -1
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +1 -0
- data/lib/ruby_smb/smb2/packet.rb +2 -0
- data/lib/ruby_smb/smb2/pipe.rb +4 -0
- data/lib/ruby_smb/smb2.rb +11 -0
- data/lib/ruby_smb/smb_error.rb +110 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +2 -0
- data/ruby_smb.gemspec +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +1 -2
- 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 +3792 -1373
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +2 -2
- 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 +29 -28
- 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 +56 -79
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +19 -29
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +9 -15
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +22 -22
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +18 -14
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +5 -4
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +1 -5
- 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 +4 -41
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +4 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +4 -52
- 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 -25
- 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_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 +10 -22
- data/spec/lib/ruby_smb/dcerpc/winreg/regsam_spec.rb +4 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +0 -12
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +18 -47
- 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/field/nt_status_spec.rb +6 -2
- data/spec/lib/ruby_smb/field/string16_spec.rb +22 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/authenticator_spec.rb +4 -0
- data/spec/lib/ruby_smb/gss/provider/ntlm/os_version_spec.rb +1 -1
- data/spec/lib/ruby_smb/server/server_client_spec.rb +36 -53
- data/spec/lib/ruby_smb/server/session_spec.rb +38 -0
- data/spec/lib/ruby_smb/server/share/provider/disk_spec.rb +61 -0
- data/spec/lib/ruby_smb/server/share/provider/pipe_spec.rb +31 -0
- data/spec/lib/ruby_smb/server/share/provider_spec.rb +13 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
- data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +8 -2
- data/spec/lib/ruby_smb/smb2/{create_context_spec.rb → create_context/create_context_request_spec.rb} +1 -1
- data/spec/lib/ruby_smb/smb2/packet/create_request_spec.rb +5 -5
- data/spec/lib/ruby_smb/smb2/packet/create_response_spec.rb +9 -5
- data/spec/lib/ruby_smb/smb2/packet/query_directory_response_spec.rb +3 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +2 -3
- metadata +129 -10
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
- data/lib/ruby_smb/smb1/create_actions.rb +0 -20
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
|
@@ -8,28 +8,30 @@ module RubySMB
|
|
|
8
8
|
require 'ruby_smb/signing'
|
|
9
9
|
require 'ruby_smb/server/server_client/negotiation'
|
|
10
10
|
require 'ruby_smb/server/server_client/session_setup'
|
|
11
|
+
require 'ruby_smb/server/server_client/share_io'
|
|
12
|
+
require 'ruby_smb/server/server_client/tree_connect'
|
|
11
13
|
|
|
12
14
|
include RubySMB::Signing
|
|
13
15
|
include RubySMB::Server::ServerClient::Negotiation
|
|
14
16
|
include RubySMB::Server::ServerClient::SessionSetup
|
|
17
|
+
include RubySMB::Server::ServerClient::ShareIO
|
|
18
|
+
include RubySMB::Server::ServerClient::TreeConnect
|
|
15
19
|
|
|
16
|
-
attr_reader :dialect, :
|
|
20
|
+
attr_reader :dialect, :session_table
|
|
17
21
|
|
|
18
22
|
# @param [Server] server the server that accepted this connection
|
|
19
23
|
# @param [Dispatcher::Socket] dispatcher the connection's socket dispatcher
|
|
20
24
|
def initialize(server, dispatcher)
|
|
21
25
|
@server = server
|
|
22
26
|
@dispatcher = dispatcher
|
|
23
|
-
@state = :negotiate
|
|
24
27
|
@dialect = nil
|
|
25
|
-
@message_id = 0
|
|
26
|
-
@session_id = nil
|
|
27
|
-
@session_key = nil
|
|
28
28
|
@gss_authenticator = server.gss_provider.new_authenticator(self)
|
|
29
|
-
@identity = nil
|
|
30
|
-
@tree_connections = {}
|
|
31
29
|
@preauth_integrity_hash_algorithm = nil
|
|
32
30
|
@preauth_integrity_hash_value = nil
|
|
31
|
+
@in_packet_queue = []
|
|
32
|
+
|
|
33
|
+
# session id => session instance
|
|
34
|
+
@session_table = {}
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
#
|
|
@@ -52,18 +54,75 @@ module RubySMB
|
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
#
|
|
55
|
-
# Handle
|
|
56
|
-
#
|
|
57
|
+
# Handle a request after the dialect has been negotiated. This is the main
|
|
58
|
+
# handler for all requests after the connection has been established. If a
|
|
59
|
+
# request handler raises NotImplementedError, the server will respond to
|
|
60
|
+
# the client with NT Status STATUS_NOT_SUPPORTED.
|
|
57
61
|
#
|
|
58
62
|
# @param [String] raw_request the request that should be handled
|
|
59
|
-
def
|
|
63
|
+
def handle_smb(raw_request)
|
|
60
64
|
response = nil
|
|
61
65
|
|
|
62
66
|
case raw_request[0...4].unpack1('L>')
|
|
63
67
|
when RubySMB::SMB1::SMB_PROTOCOL_ID
|
|
64
|
-
|
|
68
|
+
begin
|
|
69
|
+
header = RubySMB::SMB1::SMBHeader.read(raw_request)
|
|
70
|
+
rescue IOError => e
|
|
71
|
+
logger.error("Caught a #{e.class} while reading the SMB1 header (#{e.message})")
|
|
72
|
+
disconnect!
|
|
73
|
+
return
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
begin
|
|
77
|
+
response = handle_smb1(raw_request, header)
|
|
78
|
+
rescue NotImplementedError
|
|
79
|
+
logger.error("Caught a NotImplementedError while handling a #{SMB1::Commands.name(header.command)} request")
|
|
80
|
+
response = RubySMB::SMB1::Packet::EmptyPacket.new
|
|
81
|
+
response.smb_header.nt_status = WindowsError::NTStatus::STATUS_NOT_SUPPORTED
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
unless response.nil?
|
|
85
|
+
# set these header fields if they were not initialized
|
|
86
|
+
if response.is_a?(SMB1::Packet::EmptyPacket)
|
|
87
|
+
response.smb_header.command = header.command if response.smb_header.command == 0
|
|
88
|
+
response.smb_header.flags.reply = 1
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
response.smb_header.pid_high = header.pid_high if response.smb_header.pid_high == 0
|
|
92
|
+
response.smb_header.tid = header.tid if response.smb_header.tid == 0
|
|
93
|
+
response.smb_header.pid_low = header.pid_low if response.smb_header.pid_low == 0
|
|
94
|
+
response.smb_header.uid = header.uid if response.smb_header.uid == 0
|
|
95
|
+
response.smb_header.mid = header.mid if response.smb_header.mid == 0
|
|
96
|
+
end
|
|
65
97
|
when RubySMB::SMB2::SMB2_PROTOCOL_ID
|
|
66
|
-
|
|
98
|
+
begin
|
|
99
|
+
header = RubySMB::SMB2::SMB2Header.read(raw_request)
|
|
100
|
+
rescue IOError => e
|
|
101
|
+
logger.error("Caught a #{e.class} while reading the SMB2 header (#{e.message})")
|
|
102
|
+
disconnect!
|
|
103
|
+
return
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
response = handle_smb2(raw_request, header)
|
|
108
|
+
rescue NotImplementedError
|
|
109
|
+
logger.error("Caught a NotImplementedError while handling a #{SMB2::Commands.name(header.command)} request")
|
|
110
|
+
response = SMB2::Packet::ErrorPacket.new
|
|
111
|
+
response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NOT_SUPPORTED
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
unless response.nil?
|
|
115
|
+
# set these header fields if they were not initialized
|
|
116
|
+
if response.is_a?(SMB2::Packet::ErrorPacket)
|
|
117
|
+
response.smb2_header.command = header.command if response.smb2_header.command == 0
|
|
118
|
+
response.smb2_header.flags.reply = 1
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
response.smb2_header.credits = 1 if response.smb2_header.credits == 0
|
|
122
|
+
response.smb2_header.message_id = header.message_id if response.smb2_header.message_id == 0
|
|
123
|
+
response.smb2_header.session_id = header.session_id if response.smb2_header.session_id == 0
|
|
124
|
+
response.smb2_header.tree_id = header.tree_id if response.smb2_header.tree_id == 0
|
|
125
|
+
end
|
|
67
126
|
end
|
|
68
127
|
|
|
69
128
|
if response.nil?
|
|
@@ -96,25 +155,33 @@ module RubySMB
|
|
|
96
155
|
break
|
|
97
156
|
end
|
|
98
157
|
|
|
99
|
-
|
|
100
|
-
when :negotiate
|
|
158
|
+
if @dialect.nil?
|
|
101
159
|
handle_negotiate(raw_request)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
handle_authenticated(raw_request)
|
|
160
|
+
logger.info("Negotiated dialect: #{RubySMB::Dialect[@dialect].full_name}") unless @dialect.nil?
|
|
161
|
+
else
|
|
162
|
+
handle_smb(raw_request)
|
|
106
163
|
end
|
|
107
164
|
|
|
108
165
|
break if @dispatcher.tcp_socket.closed?
|
|
109
166
|
end
|
|
167
|
+
|
|
168
|
+
disconnect!
|
|
110
169
|
end
|
|
111
170
|
|
|
112
171
|
#
|
|
113
172
|
# Disconnect the remote client.
|
|
114
173
|
#
|
|
115
174
|
def disconnect!
|
|
116
|
-
@
|
|
117
|
-
@dispatcher.tcp_socket.close
|
|
175
|
+
@dialect = nil
|
|
176
|
+
@dispatcher.tcp_socket.close unless @dispatcher.tcp_socket.closed?
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
#
|
|
180
|
+
# The logger object associated with this instance.
|
|
181
|
+
#
|
|
182
|
+
# @return [Logger]
|
|
183
|
+
def logger
|
|
184
|
+
@server.logger
|
|
118
185
|
end
|
|
119
186
|
|
|
120
187
|
#
|
|
@@ -122,7 +189,24 @@ module RubySMB
|
|
|
122
189
|
#
|
|
123
190
|
# @return [String] the raw packet
|
|
124
191
|
def recv_packet
|
|
125
|
-
@
|
|
192
|
+
return @in_packet_queue.shift if @in_packet_queue.length > 0
|
|
193
|
+
|
|
194
|
+
packet = @dispatcher.recv_packet
|
|
195
|
+
if packet && packet.length >= 4 && packet[0...4].unpack1('L>') == RubySMB::SMB2::SMB2_PROTOCOL_ID
|
|
196
|
+
header = RubySMB::SMB2::SMB2Header.read(packet)
|
|
197
|
+
unless header.next_command == 0
|
|
198
|
+
until header.next_command == 0
|
|
199
|
+
@in_packet_queue.push(packet[0...header.next_command])
|
|
200
|
+
packet = packet[header.next_command..-1]
|
|
201
|
+
header = RubySMB::SMB2::SMB2Header.read(packet)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
@in_packet_queue.push(packet)
|
|
205
|
+
packet = @in_packet_queue.shift
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
packet
|
|
126
210
|
end
|
|
127
211
|
|
|
128
212
|
#
|
|
@@ -130,12 +214,20 @@ module RubySMB
|
|
|
130
214
|
#
|
|
131
215
|
# @param [GenericPacket] packet the packet to send
|
|
132
216
|
def send_packet(packet)
|
|
133
|
-
|
|
134
|
-
|
|
217
|
+
case metadialect&.order
|
|
218
|
+
when Dialect::ORDER_SMB1
|
|
219
|
+
session_id = packet.smb_header.uid
|
|
220
|
+
when Dialect::ORDER_SMB2
|
|
221
|
+
session_id = packet.smb2_header.session_id
|
|
222
|
+
end
|
|
223
|
+
session = @session_table[session_id]
|
|
224
|
+
|
|
225
|
+
unless session.nil? || session.is_anonymous || session.key.nil?
|
|
226
|
+
case metadialect&.family
|
|
135
227
|
when Dialect::FAMILY_SMB2
|
|
136
|
-
packet = smb2_sign(packet)
|
|
228
|
+
packet = Signing::smb2_sign(packet, session.key)
|
|
137
229
|
when Dialect::FAMILY_SMB3
|
|
138
|
-
packet = smb3_sign(packet)
|
|
230
|
+
packet = Signing::smb3_sign(packet, session.key, @dialect, @preauth_integrity_hash_value)
|
|
139
231
|
end
|
|
140
232
|
end
|
|
141
233
|
|
|
@@ -158,6 +250,103 @@ module RubySMB
|
|
|
158
250
|
@preauth_integrity_hash_value + data.to_binary_s
|
|
159
251
|
)
|
|
160
252
|
end
|
|
253
|
+
|
|
254
|
+
private
|
|
255
|
+
|
|
256
|
+
#
|
|
257
|
+
# Handle an SMB version 1 message.
|
|
258
|
+
#
|
|
259
|
+
# @param [String] raw_request The bytes of the entire SMB request.
|
|
260
|
+
# @param [RubySMB::SMB1::SMBHeader] header The request header.
|
|
261
|
+
# @return [RubySMB::GenericPacket]
|
|
262
|
+
def handle_smb1(raw_request, header)
|
|
263
|
+
# session = @session_table[header.uid]
|
|
264
|
+
session = nil
|
|
265
|
+
|
|
266
|
+
case header.command
|
|
267
|
+
when SMB1::Commands::SMB_COM_SESSION_SETUP_ANDX
|
|
268
|
+
dispatcher, request_class = :do_session_setup_smb1, SMB1::Packet::SessionSetupRequest
|
|
269
|
+
else
|
|
270
|
+
logger.warn("The SMB1 #{SMB1::Commands.name(header.command)} command is not supported")
|
|
271
|
+
raise NotImplementedError
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
begin
|
|
275
|
+
request = request_class.read(raw_request)
|
|
276
|
+
rescue IOError, RubySMB::Error::InvalidPacket => e
|
|
277
|
+
logger.error("Caught a #{e.class} while reading the SMB1 #{request_class} (#{e.message})")
|
|
278
|
+
response = RubySMB::SMB1::Packet::EmptyPacket.new
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
if request.is_a?(SMB1::Packet::EmptyPacket)
|
|
282
|
+
logger.error("Received an error packet for SMB1 command: #{SMB1::Commands.name(header.command)}")
|
|
283
|
+
response.smb_header.nt_status = WindowsError::NTStatus::STATUS_DATA_ERROR
|
|
284
|
+
return response
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
logger.debug("Dispatching request to #{dispatcher} (session: #{session.inspect})")
|
|
288
|
+
send(dispatcher, request, session)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
#
|
|
292
|
+
# Handle an SMB version 2 or 3 message.
|
|
293
|
+
#
|
|
294
|
+
# @param [String] raw_request The bytes of the entire SMB request.
|
|
295
|
+
# @param [RubySMB::SMB2::SMB2Header] header The request header.
|
|
296
|
+
# @return [RubySMB::GenericPacket]
|
|
297
|
+
# @raise [NotImplementedError] Raised when the requested operation is not
|
|
298
|
+
# supported.
|
|
299
|
+
def handle_smb2(raw_request, header)
|
|
300
|
+
session = @session_table[header.session_id]
|
|
301
|
+
|
|
302
|
+
if session.nil? && !(header.command == SMB2::Commands::SESSION_SETUP && header.session_id == 0)
|
|
303
|
+
response = SMB2::Packet::ErrorPacket.new
|
|
304
|
+
response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_USER_SESSION_DELETED
|
|
305
|
+
return response
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
case header.command
|
|
309
|
+
when SMB2::Commands::CLOSE
|
|
310
|
+
dispatcher, request_class = :do_close_smb2, SMB2::Packet::CloseRequest
|
|
311
|
+
when SMB2::Commands::CREATE
|
|
312
|
+
dispatcher, request_class = :do_create_smb2, SMB2::Packet::CreateRequest
|
|
313
|
+
when SMB2::Commands::IOCTL
|
|
314
|
+
dispatcher, request_class = :do_ioctl_smb2, SMB2::Packet::IoctlRequest
|
|
315
|
+
when SMB2::Commands::LOGOFF
|
|
316
|
+
dispatcher, request_class = :do_logoff_smb2, SMB2::Packet::LogoffRequest
|
|
317
|
+
when SMB2::Commands::QUERY_DIRECTORY
|
|
318
|
+
dispatcher, request_class = :do_query_directory_smb2, SMB2::Packet::QueryDirectoryRequest
|
|
319
|
+
when SMB2::Commands::QUERY_INFO
|
|
320
|
+
dispatcher, request_class = :do_query_info_smb2, SMB2::Packet::QueryInfoRequest
|
|
321
|
+
when SMB2::Commands::READ
|
|
322
|
+
dispatcher, request_class = :do_read_smb2, SMB2::Packet::ReadRequest
|
|
323
|
+
when SMB2::Commands::SESSION_SETUP
|
|
324
|
+
dispatcher, request_class = :do_session_setup_smb2, SMB2::Packet::SessionSetupRequest
|
|
325
|
+
when SMB2::Commands::TREE_CONNECT
|
|
326
|
+
dispatcher, request_class = :do_tree_connect_smb2, SMB2::Packet::TreeConnectRequest
|
|
327
|
+
when SMB2::Commands::TREE_DISCONNECT
|
|
328
|
+
dispatcher, request_class = :do_tree_disconnect_smb2, SMB2::Packet::TreeDisconnectRequest
|
|
329
|
+
else
|
|
330
|
+
logger.warn("The SMB2 #{SMB2::Commands.name(header.command)} command is not supported")
|
|
331
|
+
raise NotImplementedError
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
begin
|
|
335
|
+
request = request_class.read(raw_request)
|
|
336
|
+
rescue IOError, RubySMB::Error::InvalidPacket => e
|
|
337
|
+
logger.error("Caught a #{e.class} while reading the SMB2 #{request_class} (#{e.message})")
|
|
338
|
+
response = RubySMB::SMB2::Packet::ErrorPacket.new
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
if request.is_a?(SMB2::Packet::ErrorPacket)
|
|
342
|
+
logger.error("Received an error packet for SMB2 command: #{SMB2::Commands.name(header.command)}")
|
|
343
|
+
response.smb_header.nt_status = WindowsError::NTStatus::STATUS_DATA_ERROR
|
|
344
|
+
return response
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
logger.debug("Dispatching request to #{dispatcher} (session: #{session.inspect})")
|
|
348
|
+
send(dispatcher, request, session)
|
|
349
|
+
end
|
|
161
350
|
end
|
|
162
351
|
end
|
|
163
352
|
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
class Server
|
|
3
|
+
# The object representing a single anonymous, guest or authenticated session.
|
|
4
|
+
# @see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/ea10b7ae-b053-4e4c-ab31-a48f7d0a79af
|
|
5
|
+
class Session
|
|
6
|
+
# @param [Integer] id This session's unique identifier.
|
|
7
|
+
# @param [String] key This session's key.
|
|
8
|
+
# @param [Symbol] state The state that this session is in.
|
|
9
|
+
# @param user_id The identity of the user associated with this session.
|
|
10
|
+
def initialize(id, key: nil, state: :in_progress, user_id: nil)
|
|
11
|
+
@id = id
|
|
12
|
+
@key = key
|
|
13
|
+
@user_id = user_id
|
|
14
|
+
@state = state
|
|
15
|
+
@signing_required = false
|
|
16
|
+
# tree id => provider processor instance
|
|
17
|
+
@tree_connect_table = {}
|
|
18
|
+
@creation_time = Time.now
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def inspect
|
|
22
|
+
"#<Session id: #{@id.inspect}, user_id: #{@user_id.inspect}, state: #{@state.inspect}>"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Whether or not this session is anonymous.
|
|
26
|
+
# @return [Boolean]
|
|
27
|
+
def is_anonymous
|
|
28
|
+
@user_id == Gss::Provider::IDENTITY_ANONYMOUS
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def logoff!
|
|
32
|
+
@tree_connect_table.values.each { |share_processor| share_processor.disconnect! }
|
|
33
|
+
@tree_connect_table.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This session's unique identifier.
|
|
37
|
+
# @!attribute [rw] id
|
|
38
|
+
# @return [Integer]
|
|
39
|
+
attr_accessor :id
|
|
40
|
+
|
|
41
|
+
# This session's key.
|
|
42
|
+
# @!attribute [rw] key
|
|
43
|
+
# @return [String]
|
|
44
|
+
attr_accessor :key
|
|
45
|
+
|
|
46
|
+
# The identity of the authenticated user.
|
|
47
|
+
# @!attribute [rw] user_id
|
|
48
|
+
attr_accessor :user_id
|
|
49
|
+
|
|
50
|
+
# The state that the session is in, (:expired, :in_progress, :valid, etc.).
|
|
51
|
+
# @!attribute [rw] state
|
|
52
|
+
# @return [Symbol]
|
|
53
|
+
attr_accessor :state
|
|
54
|
+
|
|
55
|
+
# Whether or not this session requires messages to be signed.
|
|
56
|
+
# @!attribute [rw] signing_required
|
|
57
|
+
# @return [Boolean]
|
|
58
|
+
attr_accessor :signing_required
|
|
59
|
+
|
|
60
|
+
# The table of tree/share connections in use by this session.
|
|
61
|
+
# @!attribute [rw] tree_connect_table
|
|
62
|
+
# @return [Hash]
|
|
63
|
+
attr_accessor :tree_connect_table
|
|
64
|
+
|
|
65
|
+
# The time at which this session was created.
|
|
66
|
+
# @!attribute [r] creation_time
|
|
67
|
+
# @return [Time]
|
|
68
|
+
attr_reader :creation_time
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|