ruby_smb 2.0.9 → 2.0.13
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 -15
- data/examples/auth_capture.rb +71 -0
- data/examples/dump_secrets_from_sid.rb +207 -0
- data/examples/enum_domain_users.rb +75 -0
- data/examples/get_computer_info.rb +42 -0
- data/examples/query_service_status.rb +42 -4
- data/lib/ruby_smb/client/negotiation.rb +1 -1
- data/lib/ruby_smb/client.rb +10 -20
- 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/dialect.rb +45 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/field/file_time.rb +1 -1
- data/lib/ruby_smb/field/string16.rb +5 -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/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/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/pipe.rb +4 -0
- data/lib/ruby_smb/smb1/tree.rb +1 -1
- data/lib/ruby_smb/smb2/negotiate_context.rb +18 -2
- 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 +4 -0
- data/lib/ruby_smb/smb2/tree.rb +1 -1
- data/lib/ruby_smb/smb2.rb +3 -1
- data/lib/ruby_smb/version.rb +1 -1
- data/lib/ruby_smb.rb +2 -1
- data/spec/lib/ruby_smb/client_spec.rb +8 -11
- 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/string16_spec.rb +22 -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/server/server_client_spec.rb +156 -0
- data/spec/lib/ruby_smb/server_spec.rb +32 -0
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +18 -37
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +4 -4
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +18 -16
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +5 -5
- data/spec/support/bin_helper.rb +9 -0
- data.tar.gz.sig +2 -1
- metadata +119 -6
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/client/signing.rb +0 -64
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +0 -38
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +0 -135
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RubySMB::Gss::Provider::NTLM do
|
|
4
|
+
let(:provider) { described_class.new }
|
|
5
|
+
|
|
6
|
+
it { is_expected.to respond_to :allow_anonymous }
|
|
7
|
+
it { is_expected.to respond_to :default_domain }
|
|
8
|
+
|
|
9
|
+
describe '#initialize' do
|
|
10
|
+
it 'defaults to false for allowing anonymous access' do
|
|
11
|
+
expect(provider.allow_anonymous).to be false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'defaults to a default domain of WORKGROUP' do
|
|
15
|
+
expect(provider.default_domain).to eq 'WORKGROUP'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'defaults to a random challenge generator' do
|
|
19
|
+
expect(provider.generate_server_challenge).to_not eq provider.generate_server_challenge
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '#generate_server_challenge' do
|
|
24
|
+
it 'generates a valid 8-byte challenge' do
|
|
25
|
+
challenge = provider.generate_server_challenge
|
|
26
|
+
expect(challenge).to be_a String
|
|
27
|
+
expect(challenge.length).to eq 8
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should take a generator block' do
|
|
31
|
+
random_challenge = Random.new.bytes(8)
|
|
32
|
+
provider.generate_server_challenge do
|
|
33
|
+
random_challenge
|
|
34
|
+
end
|
|
35
|
+
expect(provider.generate_server_challenge).to eq random_challenge
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '#get_account' do
|
|
40
|
+
let(:username) { 'RubySMB' }
|
|
41
|
+
let(:password) { 'password' }
|
|
42
|
+
let(:domain) { 'WORKGROUP' }
|
|
43
|
+
|
|
44
|
+
context 'when getting accounts' do
|
|
45
|
+
before(:each) do
|
|
46
|
+
provider.put_account(username, password)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'should return nil for an unknown account' do
|
|
50
|
+
account = provider.get_account('Spencer')
|
|
51
|
+
expect(account).to be_nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should work with a case sensitive name' do
|
|
55
|
+
account = provider.get_account(username)
|
|
56
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
57
|
+
expect(account.username).to eq username
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should work with a case insensitive name' do
|
|
61
|
+
account = provider.get_account(username.downcase)
|
|
62
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
63
|
+
expect(account.username).to eq username
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should work with a case sensitive domain' do
|
|
67
|
+
account = provider.get_account(username, domain: domain)
|
|
68
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
69
|
+
expect(account.domain).to eq domain
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'should work with a case insensitive domain' do
|
|
73
|
+
account = provider.get_account(username, domain: domain.downcase)
|
|
74
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
75
|
+
expect(account.domain).to eq domain
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should work with the special . domain' do
|
|
79
|
+
account = provider.get_account(username, domain: '.')
|
|
80
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
81
|
+
expect(account.domain).to eq domain
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# UTF-16LE is optionally used for encoding some Net-NTLM message fields, the #get_account method should handle it
|
|
85
|
+
# transparently
|
|
86
|
+
it 'should work with a UTF16-LE name' do
|
|
87
|
+
account = provider.get_account(username.encode('UTF-16LE'))
|
|
88
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
89
|
+
expect(account.username).to eq username
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'should work with a UTF16-LE domain' do
|
|
93
|
+
account = provider.get_account(username, domain: domain.encode('UTF-16LE'))
|
|
94
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
95
|
+
expect(account.domain).to eq domain
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
context 'when putting accounts' do
|
|
100
|
+
it 'should accept new accounts with the default domain' do
|
|
101
|
+
provider.put_account(username, password)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
after(:each) do
|
|
105
|
+
account = provider.get_account(username, domain: domain)
|
|
106
|
+
expect(account).to be_a RubySMB::Gss::Provider::NTLM::Account
|
|
107
|
+
expect(account.username).to eq username
|
|
108
|
+
expect(account.password).to eq password
|
|
109
|
+
expect(account.domain).to eq domain
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
RSpec.describe RubySMB::Server::ServerClient do
|
|
2
|
+
let(:server) { RubySMB::Server.new(server_sock: ::TCPServer.new(0)) }
|
|
3
|
+
let(:sock) { double('Socket', peeraddr: '192.168.1.5') }
|
|
4
|
+
let(:dispatcher) { RubySMB::Dispatcher::Socket.new(sock) }
|
|
5
|
+
subject(:server_client) { described_class.new(server, dispatcher) }
|
|
6
|
+
|
|
7
|
+
it { is_expected.to respond_to :dialect }
|
|
8
|
+
it { is_expected.to respond_to :identity }
|
|
9
|
+
it { is_expected.to respond_to :state }
|
|
10
|
+
it { is_expected.to respond_to :session_key }
|
|
11
|
+
|
|
12
|
+
describe '#disconnect!' do
|
|
13
|
+
it 'closes the socket' do
|
|
14
|
+
expect(dispatcher.tcp_socket).to receive(:close).with(no_args).and_return(nil)
|
|
15
|
+
server_client.disconnect!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#initialize' do
|
|
20
|
+
it 'starts in the negotiate state' do
|
|
21
|
+
expect(server_client.state).to eq :negotiate
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'starts without a dialect' do
|
|
25
|
+
expect(server_client.dialect).to be_nil
|
|
26
|
+
expect(server_client.metadialect).to be_nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'starts without an identity' do
|
|
30
|
+
expect(server_client.identity).to be_nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'starts without a session_key' do
|
|
34
|
+
expect(server_client.session_key).to be_nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'creates a new authenticator instance' do
|
|
38
|
+
expect(server.gss_provider).to receive(:new_authenticator).and_call_original
|
|
39
|
+
described_class.new(server, dispatcher)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#process_gss' do
|
|
44
|
+
before(:each) do
|
|
45
|
+
expect(server_client.instance_eval { @gss_authenticator }).to receive(:process).and_call_original
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should handle an empty GSS buffer' do
|
|
49
|
+
result = server_client.process_gss
|
|
50
|
+
expect(result).to be_a RubySMB::Gss::Provider::Result
|
|
51
|
+
expect(result.nt_status).to eq WindowsError::NTStatus::STATUS_SUCCESS
|
|
52
|
+
expect(result.buffer).to_not be_empty
|
|
53
|
+
expect(result.identity).to be_nil
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe '#recv_packet' do
|
|
58
|
+
it 'receives a new packet from the dispatcher' do
|
|
59
|
+
expect(dispatcher).to receive(:recv_packet).with(no_args)
|
|
60
|
+
server_client.recv_packet
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe '#run' do
|
|
65
|
+
let(:packet) { Random.new.bytes(16) }
|
|
66
|
+
before(:each) do
|
|
67
|
+
expect(server_client).to receive(:recv_packet).and_return(packet)
|
|
68
|
+
# this hook should ensure that the dispatcher loop returns after processing a single request
|
|
69
|
+
expect(dispatcher.tcp_socket).to receive(:closed?).and_return(true)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'calls #handle_negotiate when the state is negotiate' do
|
|
73
|
+
expect(server_client).to receive(:handle_negotiate).with(packet).and_return(nil)
|
|
74
|
+
server_client.instance_eval { @state = :negotiate }
|
|
75
|
+
server_client.run
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'calls #handle_session_setup when the state is session_setup' do
|
|
79
|
+
expect(server_client).to receive(:handle_session_setup).with(packet).and_return(nil)
|
|
80
|
+
server_client.instance_eval { @state = :session_setup }
|
|
81
|
+
server_client.run
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'calls #authenticated when the state is authenticated' do
|
|
85
|
+
expect(server_client).to receive(:handle_authenticated).with(packet).and_return(nil)
|
|
86
|
+
server_client.instance_eval { @state = :authenticated }
|
|
87
|
+
server_client.run
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe '#send_packet' do
|
|
92
|
+
let(:packet) { RubySMB::GenericPacket.new }
|
|
93
|
+
|
|
94
|
+
before(:each) do
|
|
95
|
+
expect(dispatcher).to receive(:send_packet).with(packet).and_return(nil)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'sends a packet to the dispatcher' do
|
|
99
|
+
server_client.send_packet(packet)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
%w{ 0x0202 0x0210 0x0300 0x0302 0x0311 }.each do |dialect|
|
|
103
|
+
context "when the dialect is #{dialect}" do
|
|
104
|
+
before(:each) do
|
|
105
|
+
server_client.instance_eval { @dialect = dialect }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'and the state is authenticated' do
|
|
109
|
+
before(:each) do
|
|
110
|
+
server_client.instance_eval { @state = :authenticated }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'and the identity is anonymous' do
|
|
114
|
+
before(:each) do
|
|
115
|
+
server_client.instance_eval { @identity = RubySMB::Gss::Provider::IDENTITY_ANONYMOUS }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'does not sign packets' do
|
|
119
|
+
expect(server_client).to_not receive(:smb2_sign)
|
|
120
|
+
expect(server_client).to_not receive(:smb3_sign)
|
|
121
|
+
server_client.send_packet(packet)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context 'and the identity is not anonymous' do
|
|
126
|
+
before(:each) do
|
|
127
|
+
server_client.instance_eval { @identity = 'WORKGROUP\RubySMB'; @session_key = Random.new.bytes(16) }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'does sign packets' do
|
|
131
|
+
packet = RubySMB::GenericPacket.new
|
|
132
|
+
dialect_family = RubySMB::Dialect[dialect].family
|
|
133
|
+
if dialect_family == RubySMB::Dialect::FAMILY_SMB2
|
|
134
|
+
expect(server_client).to receive(:smb2_sign).with(packet).and_return(packet)
|
|
135
|
+
expect(server_client).to_not receive(:smb3_sign)
|
|
136
|
+
elsif dialect_family == RubySMB::Dialect::FAMILY_SMB3
|
|
137
|
+
expect(server_client).to receive(:smb3_sign).with(packet).and_return(packet)
|
|
138
|
+
expect(server_client).to_not receive(:smb2_sign)
|
|
139
|
+
end
|
|
140
|
+
server_client.send_packet(packet)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
describe '#update_preauth_hash' do
|
|
149
|
+
it 'raises an EncryptionError exception if the preauth integrity hash algorithm is not known' do
|
|
150
|
+
expect { server_client.update_preauth_hash('Test') }.to raise_error(
|
|
151
|
+
RubySMB::Error::EncryptionError,
|
|
152
|
+
'Cannot compute the Preauth Integrity Hash value: Preauth Integrity Hash Algorithm is nil'
|
|
153
|
+
)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
RSpec.describe RubySMB::Server do
|
|
2
|
+
before(:each) do
|
|
3
|
+
allow(::TCPServer).to receive(:new).and_return(::TCPServer.new(0))
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it { is_expected.to respond_to :dialects }
|
|
7
|
+
it { is_expected.to respond_to :gss_provider }
|
|
8
|
+
it { is_expected.to respond_to :guid }
|
|
9
|
+
|
|
10
|
+
describe '#initialize' do
|
|
11
|
+
it 'should bind to TCP port 445 by default' do
|
|
12
|
+
expect(::TCPServer).to receive(:new).with(445).and_return(::TCPServer.new(0))
|
|
13
|
+
described_class.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'should create a new NTLM GSS provider by default' do
|
|
17
|
+
expect(RubySMB::Gss::Provider::NTLM).to receive(:new).and_call_original
|
|
18
|
+
described_class.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'should generate a random 16-byte GUID' do
|
|
22
|
+
server_guid = described_class.new.guid
|
|
23
|
+
expect(server_guid).to be_a String
|
|
24
|
+
expect(server_guid.length).to eq 16
|
|
25
|
+
expect(server_guid).to_not eq described_class.new.guid
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should support some dialects' do
|
|
29
|
+
expect(described_class.new.dialects).to_not be_empty
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -140,45 +140,26 @@ RSpec.describe RubySMB::SMB1::Pipe do
|
|
|
140
140
|
expect(pipe.size_on_disk).to eq(nt_create_andx_response.parameter_block.allocation_size)
|
|
141
141
|
end
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
context 'with \'winreg\' filename' do
|
|
158
|
-
it 'extends Winreg class' do
|
|
159
|
-
pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: 'winreg')
|
|
160
|
-
expect(pipe.respond_to?(:has_registry_key?)).to be true
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
context 'with \'\\winreg\' filename' do
|
|
165
|
-
it 'extends Winreg class' do
|
|
166
|
-
pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: '\\winreg')
|
|
167
|
-
expect(pipe.respond_to?(:has_registry_key?)).to be true
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
context 'with \'svcctl\' filename' do
|
|
172
|
-
it 'extends svcctl class' do
|
|
173
|
-
pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: 'svcctl')
|
|
174
|
-
expect(pipe.respond_to?(:query_service_config)).to be true
|
|
143
|
+
{
|
|
144
|
+
netlogon: RubySMB::Dcerpc::Netlogon,
|
|
145
|
+
srvsvc: RubySMB::Dcerpc::Srvsvc,
|
|
146
|
+
svcctl: RubySMB::Dcerpc::Svcctl,
|
|
147
|
+
winreg: RubySMB::Dcerpc::Winreg,
|
|
148
|
+
samr: RubySMB::Dcerpc::Samr,
|
|
149
|
+
wkssvc: RubySMB::Dcerpc::Wkssvc
|
|
150
|
+
}.each do |endpoint, klass|
|
|
151
|
+
context "with \'#{endpoint}\' filename" do
|
|
152
|
+
it "extends #{klass} class" do
|
|
153
|
+
pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: endpoint.to_s)
|
|
154
|
+
expect(pipe).to be_a klass
|
|
155
|
+
end
|
|
175
156
|
end
|
|
176
|
-
end
|
|
177
157
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
158
|
+
context "with \'\\#{endpoint}\' filename" do
|
|
159
|
+
it "extends #{klass} class" do
|
|
160
|
+
pipe = described_class.new(tree: tree, response: nt_create_andx_response, name: "\\#{endpoint.to_s}")
|
|
161
|
+
expect(pipe).to be_a klass
|
|
162
|
+
end
|
|
182
163
|
end
|
|
183
164
|
end
|
|
184
165
|
end
|
|
@@ -501,16 +501,16 @@ RSpec.describe RubySMB::SMB1::Tree do
|
|
|
501
501
|
it 'calls #open_file with the provided options' do
|
|
502
502
|
opts[:filename] ='\\test'
|
|
503
503
|
expect(tree).to receive(:open_file).with(opts)
|
|
504
|
-
tree.open_pipe(opts)
|
|
504
|
+
tree.open_pipe(**opts)
|
|
505
505
|
end
|
|
506
506
|
|
|
507
507
|
it 'prepends the filename with \\ if needed' do
|
|
508
|
-
expect(tree).to receive(:open_file).with(
|
|
509
|
-
tree.open_pipe(opts)
|
|
508
|
+
expect(tree).to receive(:open_file).with(filename: '\\test', write: true)
|
|
509
|
+
tree.open_pipe(**opts)
|
|
510
510
|
end
|
|
511
511
|
|
|
512
512
|
it 'does not modify the original option hash' do
|
|
513
|
-
tree.open_pipe(opts)
|
|
513
|
+
tree.open_pipe(**opts)
|
|
514
514
|
expect(opts).to eq( { filename: 'test', write: true } )
|
|
515
515
|
end
|
|
516
516
|
end
|
|
@@ -162,7 +162,7 @@ RSpec.describe RubySMB::SMB2::CompressionCapabilities do
|
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
RSpec.describe RubySMB::SMB2::NetnameNegotiateContextId
|
|
165
|
+
RSpec.describe RubySMB::SMB2::NetnameNegotiateContextId do
|
|
166
166
|
subject(:capability) { described_class.new }
|
|
167
167
|
|
|
168
168
|
it { is_expected.to respond_to :net_name }
|
|
@@ -173,7 +173,7 @@ RSpec.describe RubySMB::SMB2::NetnameNegotiateContextId do
|
|
|
173
173
|
|
|
174
174
|
describe '#net_name' do
|
|
175
175
|
it 'is a unicode string' do
|
|
176
|
-
expect(capability.net_name).to be_a RubySMB::Field::
|
|
176
|
+
expect(capability.net_name).to be_a RubySMB::Field::String16
|
|
177
177
|
end
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -146,24 +146,26 @@ RSpec.describe RubySMB::SMB2::Pipe do
|
|
|
146
146
|
expect(pipe.size_on_disk).to eq(create_response.allocation_size)
|
|
147
147
|
end
|
|
148
148
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
149
|
+
{
|
|
150
|
+
netlogon: RubySMB::Dcerpc::Netlogon,
|
|
151
|
+
srvsvc: RubySMB::Dcerpc::Srvsvc,
|
|
152
|
+
svcctl: RubySMB::Dcerpc::Svcctl,
|
|
153
|
+
winreg: RubySMB::Dcerpc::Winreg,
|
|
154
|
+
samr: RubySMB::Dcerpc::Samr,
|
|
155
|
+
wkssvc: RubySMB::Dcerpc::Wkssvc
|
|
156
|
+
}.each do |endpoint, klass|
|
|
157
|
+
context "with \'#{endpoint}\' filename" do
|
|
158
|
+
it "extends #{klass} class" do
|
|
159
|
+
pipe = described_class.new(tree: tree, response: create_response, name: endpoint.to_s)
|
|
160
|
+
expect(pipe).to be_a klass
|
|
161
|
+
end
|
|
160
162
|
end
|
|
161
|
-
end
|
|
162
163
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
context "with \'\\#{endpoint}\' filename" do
|
|
165
|
+
it "extends #{klass} class" do
|
|
166
|
+
pipe = described_class.new(tree: tree, response: create_response, name: "\\#{endpoint.to_s}")
|
|
167
|
+
expect(pipe).to be_a klass
|
|
168
|
+
end
|
|
167
169
|
end
|
|
168
170
|
end
|
|
169
171
|
end
|
|
@@ -540,17 +540,17 @@ RSpec.describe RubySMB::SMB2::Tree do
|
|
|
540
540
|
|
|
541
541
|
it 'calls #open_file with the provided options' do
|
|
542
542
|
opts[:filename] ='test'
|
|
543
|
-
expect(tree).to receive(:open_file).with(opts)
|
|
544
|
-
tree.open_pipe(opts)
|
|
543
|
+
expect(tree).to receive(:open_file).with(**opts)
|
|
544
|
+
tree.open_pipe(**opts)
|
|
545
545
|
end
|
|
546
546
|
|
|
547
547
|
it 'remove the leading \\ from the filename if needed' do
|
|
548
|
-
expect(tree).to receive(:open_file).with(
|
|
549
|
-
tree.open_pipe(opts)
|
|
548
|
+
expect(tree).to receive(:open_file).with(filename: 'test', write: true)
|
|
549
|
+
tree.open_pipe(**opts)
|
|
550
550
|
end
|
|
551
551
|
|
|
552
552
|
it 'does not modify the original option hash' do
|
|
553
|
-
tree.open_pipe(opts)
|
|
553
|
+
tree.open_pipe(**opts)
|
|
554
554
|
expect(opts).to eq( { filename: '\\test', write: true } )
|
|
555
555
|
end
|
|
556
556
|
end
|
data.tar.gz.sig
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
v
|
|
1
|
+
��B����:��8i��Jis��\���x:�����1��~vk4ܧ�8H�j(�S��M� �����O��iísF�.�i����9qhK-��|.k*�����HdP���W?z��v���M_qk-Ic�����(w�<J����K�|��ۺ��M�v�<�1�o�ZSR_(���R�������0�n��5� �E�l,:\�9�{���6����5�����*sa%U�D�\S7hōu�nx���歒ӛ�6
|
|
2
|
+
:�q�k
|