File: sasl_authentication.rb

package info (click to toggle)
ruby-dalli 3.2.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 684 kB
  • sloc: ruby: 6,552; sh: 20; makefile: 4
file content (60 lines) | stat: -rw-r--r-- 2,071 bytes parent folder | download
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