class Fluent::Plugin::ForwardOutput::HandshakeProtocol
Public Class Methods
new(log:, hostname:, shared_key:, password:, username:)
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 24 def initialize(log:, hostname:, shared_key:, password:, username:) @log = log @hostname = hostname @shared_key = shared_key @password = password @username = username @shared_key_salt = generate_salt end
Public Instance Methods
invoke(sock, ri, data)
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 33 def invoke(sock, ri, data) @log.trace __callee__ case ri.state when :helo unless check_helo(ri, data) raise HeloError, 'received invalid helo message' end sock.write(generate_ping(ri).to_msgpack) ri.state = :pingpong when :pingpong succeeded, reason = check_pong(ri, data) unless succeeded raise PingpongError, reason end ri.state = :established else raise "BUG: unknown session state: #{ri.state}" end end
Private Instance Methods
check_helo(ri, message)
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 83 def check_helo(ri, message) @log.debug('checking helo') # ['HELO', options(hash)] unless message.size == 2 && message[0] == 'HELO' return false end opts = message[1] || {} # make shared_key_check failed (instead of error) if protocol version mismatch exist ri.shared_key_nonce = opts['nonce'] || '' ri.auth = opts['auth'] || '' true end
check_pong(ri, message)
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 58 def check_pong(ri, message) @log.debug('checking pong') # ['PONG', bool(authentication result), 'reason if authentication failed', # self_hostname, sha512\_hex(salt + self_hostname + nonce + sharedkey)] unless message.size == 5 && message[0] == 'PONG' return false, 'invalid format for PONG message' end _pong, auth_result, reason, hostname, shared_key_hexdigest = message unless auth_result return false, 'authentication failed: ' + reason end if hostname == @hostname return false, 'same hostname between input and output: invalid configuration' end clientside = Digest::SHA512.new.update(@shared_key_salt).update(hostname).update(ri.shared_key_nonce).update(@shared_key).hexdigest unless shared_key_hexdigest == clientside return false, 'shared key mismatch' end [true, nil] end
generate_ping(ri)
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 97 def generate_ping(ri) @log.debug('generating ping') # ['PING', self_hostname, sharedkey\_salt, sha512\_hex(sharedkey\_salt + self_hostname + nonce + shared_key), # username || '', sha512\_hex(auth\_salt + username + password) || ''] shared_key_hexdigest = Digest::SHA512.new.update(@shared_key_salt) .update(@hostname) .update(ri.shared_key_nonce) .update(@shared_key) .hexdigest ping = ['PING', @hostname, @shared_key_salt, shared_key_hexdigest] if !ri.auth.empty? if @username.nil? || @password.nil? raise PingpongError, "username and password are required" end password_hexdigest = Digest::SHA512.new.update(ri.auth).update(@username).update(@password).hexdigest ping.push(@username, password_hexdigest) else ping.push('', '') end ping end
generate_salt()
click to toggle source
# File lib/fluent/plugin/out_forward/handshake_protocol.rb, line 120 def generate_salt SecureRandom.hex(16) end