1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
# frozen_string_literal: true
module Dalli
module Protocol
class Binary
##
# Code to support SASL authentication
##
module SaslAuthentication
def perform_auth_negotiation
write(RequestFormatter.standard_request(opkey: :auth_negotiation))
status, content = response_processor.auth_response
return [status, []] if content.nil?
# Substitute spaces for the \x00 returned by
# memcached as a separator for easier
content&.tr!("\u0000", ' ')
mechanisms = content&.split
[status, mechanisms]
end
PLAIN_AUTH = 'PLAIN'
def supported_mechanisms!(mechanisms)
unless mechanisms.include?(PLAIN_AUTH)
raise NotImplementedError,
'Dalli only supports the PLAIN authentication mechanism'
end
[PLAIN_AUTH]
end
def authenticate_with_plain
write(RequestFormatter.standard_request(opkey: :auth_request,
key: PLAIN_AUTH,
value: "\x0#{username}\x0#{password}"))
@response_processor.auth_response
end
def authenticate_connection
Dalli.logger.info { "Dalli/SASL authenticating as #{username}" }
status, mechanisms = perform_auth_negotiation
return Dalli.logger.debug('Authentication not required/supported by server') if status == 0x81
supported_mechanisms!(mechanisms)
status, content = authenticate_with_plain
return Dalli.logger.info("Dalli/SASL: #{content}") if status.zero?
raise Dalli::DalliError, "Error authenticating: 0x#{status.to_s(16)}" unless status == 0x21
raise NotImplementedError, 'No two-step authentication mechanisms supported'
# (step, msg) = sasl.receive('challenge', content)
# raise Dalli::NetworkError, "Authentication failed" if sasl.failed? || step != 'response'
end
end
end
end
end
|