class Thrift::SaslClientTransport
Constants
- AUTH_MECHANISM
- NEGOTIATION_STATUS
- PAYLOAD_LENGTH_BYTES
- STATUS_BYTES
Attributes
challenge[R]
sasl_complete[R]
Public Class Methods
new(transport, sasl_params={})
click to toggle source
Calls superclass method
# File lib/thrift/sasl_client_transport.rb 16 def initialize(transport, sasl_params={}) 17 super(transport) 18 @challenge = nil 19 @sasl_username = sasl_params.fetch(:username, 'anonymous') 20 @sasl_password = sasl_params.fetch(:password, 'anonymous') 21 @sasl_mechanism = sasl_params.fetch(:mechanism, 'PLAIN') 22 raise 'Unknown SASL mechanism: #{@sasl_mechanism}' unless ['PLAIN', 'GSSAPI'].include? @sasl_mechanism 23 if @sasl_mechanism == 'GSSAPI' 24 require 'gssapi' 25 @sasl_remote_principal = sasl_params[:remote_principal] 26 @sasl_remote_host = sasl_params[:remote_host] 27 @gsscli = GSSAPI::Simple.new(@sasl_remote_host, @sasl_remote_principal) 28 end 29 end
Public Instance Methods
read(sz)
click to toggle source
# File lib/thrift/sasl_client_transport.rb 31 def read(sz) 32 len, = @transport.read(PAYLOAD_LENGTH_BYTES).unpack('l>') if @rbuf.nil? 33 sz = len if len && sz > len 34 @index += sz 35 ret = @rbuf.slice(@index - sz, sz) || Bytes.empty_byte_buffer 36 if ret.length < sz 37 sz -= ret.length 38 read_into_buffer(@rbuf, [sz, len || 0].max) 39 @index = sz 40 ret += @rbuf.slice(0, sz) || Bytes.empty_byte_buffer 41 end 42 ret 43 end
read_byte()
click to toggle source
# File lib/thrift/sasl_client_transport.rb 45 def read_byte 46 reset_buffer! if @index >= @rbuf.size 47 @index += 1 48 Bytes.get_string_byte(@rbuf, @index - 1) 49 end
read_into_buffer(buffer, size)
click to toggle source
# File lib/thrift/sasl_client_transport.rb 51 def read_into_buffer(buffer, size) 52 i = 0 53 while i < size 54 reset_buffer! if @index >= @rbuf.size 55 byte = Bytes.get_string_byte(@rbuf, @index) 56 Bytes.set_string_byte(buffer, i, byte) 57 @index += 1 58 i += 1 59 end 60 i 61 end
write(buf)
click to toggle source
# File lib/thrift/sasl_client_transport.rb 63 def write(buf) 64 initiate_hand_shake unless sasl_complete 65 header = [buf.length].pack('l>') 66 @wbuf << (header + Bytes.force_binary_encoding(buf)) 67 end
Protected Instance Methods
initiate_hand_shake()
click to toggle source
# File lib/thrift/sasl_client_transport.rb 71 def initiate_hand_shake 72 if @sasl_mechanism == 'GSSAPI' 73 initiate_hand_shake_gssapi 74 else 75 initiate_hand_shake_plain 76 end 77 end
initiate_hand_shake_gssapi()
click to toggle source
# File lib/thrift/sasl_client_transport.rb 79 def initiate_hand_shake_gssapi 80 token = @gsscli.init_context 81 header = [NEGOTIATION_STATUS[:START], @sasl_mechanism.length].pack('cl>') 82 @transport.write header + @sasl_mechanism 83 header = [NEGOTIATION_STATUS[:OK], token.length].pack('cl>') 84 @transport.write header + token 85 status, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>') 86 case status 87 when NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR] 88 raise @transport.to_io.read(len) 89 when NEGOTIATION_STATUS[:COMPLETE] 90 raise "Not expecting COMPLETE at initial stage" 91 when NEGOTIATION_STATUS[:OK] 92 challenge = @transport.to_io.read len 93 unless @gsscli.init_context(challenge) 94 raise "GSSAPI: challenge provided by server could not be verified" 95 end 96 header = [NEGOTIATION_STATUS[:OK], 0].pack('cl>') 97 @transport.write header 98 status2, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>') 99 case status2 100 when NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR] 101 raise @transport.to_io.read(len) 102 when NEGOTIATION_STATUS[:COMPLETE] 103 raise "Not expecting COMPLETE at second stage" 104 when NEGOTIATION_STATUS[:OK] 105 challenge = @transport.to_io.read len 106 unwrapped = @gsscli.unwrap_message(challenge) 107 rewrapped = @gsscli.wrap_message(unwrapped) 108 header = [NEGOTIATION_STATUS[:COMPLETE], rewrapped.length].pack('cl>') 109 @transport.write header + rewrapped 110 status3, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>') 111 case status3 112 when NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR] 113 raise @transport.to_io.read(len) 114 when NEGOTIATION_STATUS[:COMPLETE] 115 s = @transport.to_io.read len 116 @sasl_complete = true 117 when NEGOTIATION_STATUS[:OK] 118 raise "Failed to complete GSS challenge exchange" 119 end 120 end 121 end 122 @sasl_complete = true 123 end
initiate_hand_shake_plain()
click to toggle source
# File lib/thrift/sasl_client_transport.rb 125 def initiate_hand_shake_plain 126 header = [NEGOTIATION_STATUS[:START], AUTH_MECHANISM.length].pack('cl>') 127 @transport.write header + AUTH_MECHANISM 128 message = "[#{AUTH_MECHANISM}]\u0000#{@sasl_username}\u0000#{@sasl_password}" 129 header = [NEGOTIATION_STATUS[:OK], message.length].pack('cl>') 130 @transport.write header + message 131 status, len = @transport.read(STATUS_BYTES + PAYLOAD_LENGTH_BYTES).unpack('cl>') 132 case status 133 when NEGOTIATION_STATUS[:BAD], NEGOTIATION_STATUS[:ERROR] 134 raise @transport.to_io.read(len) 135 when NEGOTIATION_STATUS[:COMPLETE] 136 @challenge = @transport.to_io.read len 137 when NEGOTIATION_STATUS[:OK] 138 raise "Failed to complete challenge exchange: only NONE supported currently" 139 end 140 @sasl_complete = true 141 end
Private Instance Methods
reset_buffer!()
click to toggle source
# File lib/thrift/sasl_client_transport.rb 145 def reset_buffer! 146 len, = @transport.read(PAYLOAD_LENGTH_BYTES).unpack('l>') 147 @rbuf = @transport.read(len) 148 while @rbuf.size < len 149 @rbuf << @transport.read(len - @rbuf.size) 150 end 151 @index = 0 152 end