class Impala::SASLTransport

Constants

NEGOTIATION_STATUS
PAYLOAD_LENGTH_BYTES
STATUS_BYTES

Public Class Methods

new(transport, mechanism, options={}) click to toggle source
Calls superclass method
   # File lib/impala/sasl_transport.rb
15 def initialize(transport, mechanism, options={})
16   super(transport)
17   @mechanism = mechanism.to_sym
18   @options = options
19 
20   unless [:PLAIN, :GSSAPI].include? @mechanism
21     raise "Unknown SASL mechanism: #{@mechanism}"
22   end
23 
24   if @mechanism == :GSSAPI
25     @gsscli = GSSAPI::Simple.new(@options[:remote_host], @options[:remote_principal])
26   end
27 end

Public Instance Methods

open() click to toggle source
Calls superclass method
   # File lib/impala/sasl_transport.rb
29 def open
30   super
31 
32   case @mechanism
33   when :PLAIN
34     handshake_plain!
35   when :GSSAPI
36     handshake_gssapi!
37   end
38 end

Private Instance Methods

handshake_gssapi!() click to toggle source
   # File lib/impala/sasl_transport.rb
59 def handshake_gssapi!
60   token = @gsscli.init_context
61   write_handshake_message(NEGOTIATION_STATUS[:START], 'GSSAPI')
62   write_handshake_message(NEGOTIATION_STATUS[:OK], token)
63 
64   status, msg = read_handshake_message
65   case status
66   when NEGOTIATION_STATUS[:COMPLETE]
67     raise "Unexpected COMPLETE from server"
68   when NEGOTIATION_STATUS[:OK]
69     unless @gsscli.init_context(msg)
70       raise "GSSAPI: challenge provided by server could not be verified"
71     end
72 
73     write_handshake_message(NEGOTIATION_STATUS[:OK], "")
74 
75     status, msg = read_handshake_message
76     case status
77     when NEGOTIATION_STATUS[:COMPLETE]
78       raise "Unexpected COMPLETE from server"
79     when NEGOTIATION_STATUS[:OK]
80       unwrapped = @gsscli.unwrap_message(msg)
81       rewrapped = @gsscli.wrap_message(unwrapped)
82 
83       write_handshake_message(NEGOTIATION_STATUS[:COMPLETE], rewrapped)
84 
85       status, msg = read_handshake_message
86       case status
87       when NEGOTIATION_STATUS[:COMPLETE]
88         @open = true
89       when NEGOTIATION_STATUS[:OK]
90         raise "Failed to complete GSS challenge exchange"
91       end
92     end
93   end
94 end
handshake_plain!() click to toggle source
   # File lib/impala/sasl_transport.rb
42 def handshake_plain!
43   username = @options.fetch(:username, 'anonymous')
44   password = @options.fetch(:password, 'anonymous')
45 
46   token = "[PLAIN]\u0000#{username}\u0000#{password}"
47   write_handshake_message(NEGOTIATION_STATUS[:START], 'PLAIN')
48   write_handshake_message(NEGOTIATION_STATUS[:OK], token)
49 
50   status, _ = read_handshake_message
51   case status
52   when NEGOTIATION_STATUS[:COMPLETE]
53     @open = true
54   when NEGOTIATION_STATUS[:OK]
55     raise "Failed to complete challenge exchange: only NONE supported currently"
56   end
57 end
read_handshake_message() click to toggle source
    # File lib/impala/sasl_transport.rb
 96 def read_handshake_message
 97   status, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>')
 98   body = @transport.to_io.read(len)
 99   if [NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR]].include?(status)
100     raise "Exception from server: #{body}"
101   end
102 
103   [status, body]
104 end
write_handshake_message(status, message) click to toggle source
    # File lib/impala/sasl_transport.rb
106 def write_handshake_message(status, message)
107   header = [status, message.length].pack('cl>')
108   @transport.write(header + message)
109 end