Class: Kafka::Sasl::Gssapi

Inherits:
Object
  • Object
show all
Defined in:
lib/kafka/sasl/gssapi.rb

Constant Summary collapse

GSSAPI_IDENT =
"GSSAPI"
GSSAPI_CONFIDENTIALITY =
false

Instance Method Summary collapse

Constructor Details

#initialize(logger:, principal:, keytab:) ⇒ Gssapi

Returns a new instance of Gssapi.



9
10
11
12
13
# File 'lib/kafka/sasl/gssapi.rb', line 9

def initialize(logger:, principal:, keytab:)
  @logger = TaggedLogger.new(logger)
  @principal = principal
  @keytab = keytab
end

Instance Method Details

#authenticate!(host, encoder, decoder) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/kafka/sasl/gssapi.rb', line 23

def authenticate!(host, encoder, decoder)
  load_gssapi
  initialize_gssapi_context(host)

  @encoder = encoder
  @decoder = decoder

  # send gssapi token and receive token to verify
  token_to_verify = send_and_receive_sasl_token

  # verify incoming token
  unless @gssapi_ctx.init_context(token_to_verify)
    raise Kafka::Error, "GSSAPI context verification failed."
  end

  # we can continue, so send OK
  @encoder.write([0, 2].pack('l>c'))

  # read wrapped message and return it back with principal
  handshake_messages
end

#configured?Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/kafka/sasl/gssapi.rb', line 15

def configured?
  @principal && !@principal.empty?
end

#handshake_messagesObject

Raises:



45
46
47
48
49
50
51
52
# File 'lib/kafka/sasl/gssapi.rb', line 45

def handshake_messages
  msg = @decoder.bytes
  raise Kafka::Error, "GSSAPI negotiation failed." unless msg
  # unwrap with integrity only
  msg_unwrapped = @gssapi_ctx.unwrap_message(msg, GSSAPI_CONFIDENTIALITY)
  msg_wrapped = @gssapi_ctx.wrap_message(msg_unwrapped + @principal, GSSAPI_CONFIDENTIALITY)
  @encoder.write_bytes(msg_wrapped)
end

#identObject



19
20
21
# File 'lib/kafka/sasl/gssapi.rb', line 19

def ident
  GSSAPI_IDENT
end

#initialize_gssapi_context(host) ⇒ Object



68
69
70
71
72
73
# File 'lib/kafka/sasl/gssapi.rb', line 68

def initialize_gssapi_context(host)
  @logger.debug "GSSAPI: Initializing context with #{host}, principal #{@principal}"

  @gssapi_ctx = GSSAPI::Simple.new(host, @principal, @keytab)
  @gssapi_token = @gssapi_ctx.init_context(nil)
end

#load_gssapiObject



59
60
61
62
63
64
65
66
# File 'lib/kafka/sasl/gssapi.rb', line 59

def load_gssapi
  begin
    require "gssapi"
  rescue LoadError
    @logger.error "In order to use GSSAPI authentication you need to install the `gssapi` gem."
    raise
  end
end

#send_and_receive_sasl_tokenObject



54
55
56
57
# File 'lib/kafka/sasl/gssapi.rb', line 54

def send_and_receive_sasl_token
  @encoder.write_bytes(@gssapi_token)
  @decoder.bytes
end