Class: RubySMB::Gss::Provider::Multi::Authenticator

Inherits:
Authenticator::Base
  • Object
show all
Defined in:
lib/ruby_smb/gss/provider/multi.rb

Instance Method Summary collapse

Constructor Details

#initialize(provider, server_client) ⇒ Authenticator

Returns a new instance of Authenticator.



59
60
61
62
63
64
# File 'lib/ruby_smb/gss/provider/multi.rb', line 59

def initialize(provider, server_client)
  # built lazily, so a provider that is advertised but never selected is never instantiated
  @authenticators = {}
  @selected = nil
  super
end

Instance Method Details

#process(request_buffer = nil) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ruby_smb/gss/provider/multi.rb', line 72

def process(request_buffer=nil)
  # the advertisement, listing every mechanism the server is willing to accept
  return Result.new(Gss.gss_neg_token_init(@provider.mech_types), WindowsError::NTStatus::STATUS_SUCCESS) if request_buffer.nil?

  begin
    gss_api = OpenSSL::ASN1.decode(request_buffer)
  rescue OpenSSL::ASN1::ASN1Error => e
    logger.error("Failed to parse the ASN1-encoded authentication request (#{e.message})")
    return
  end

  if negotiation_init?(gss_api)
    # a NegTokenInit names the mechanism the client chose, so this is where routing is decided
    mech_type = Gss.asn1dig(gss_api, 1, 0, 0, 0, 0)
    authenticator = authenticator_for(mech_type)
    if authenticator.nil?
      logger.warn("Client selected an unsupported GSS mechanism (#{mech_type&.oid || 'unknown'})")
      return
    end

    @selected = authenticator
  elsif @selected.nil?
    # a NegTokenResp carries no mechanism OID, so it can only be interpreted as a continuation of a
    # negotiation that has already selected one
    logger.warn('Received a GSS continuation token before any mechanism was selected')
    return
  end

  @selected.process(request_buffer)
end

#reset! ⇒ Object



66
67
68
69
70
# File 'lib/ruby_smb/gss/provider/multi.rb', line 66

def reset!
  super
  @authenticators&.each_value(&:reset!)
  @selected = nil
end

#session_key ⇒ Object

The session key belongs to whichever mechanism actually authenticated the client.



104
105
106
# File 'lib/ruby_smb/gss/provider/multi.rb', line 104

def session_key
  @selected&.session_key
end

#session_key=(value) ⇒ Object



108
109
110
# File 'lib/ruby_smb/gss/provider/multi.rb', line 108

def session_key=(value)
  @selected&.session_key = value
end