Class: Mysql::Authenticator::CachingSha2Password

Inherits:
Object
  • Object
show all
Defined in:
lib/mysql/authenticator/caching_sha2_password.rb

Overview

caching_sha2_password

Instance Method Summary collapse

Constructor Details

#initialize(protocol) ⇒ CachingSha2Password

Returns a new instance of CachingSha2Password.

Parameters:



8
9
10
# File 'lib/mysql/authenticator/caching_sha2_password.rb', line 8

def initialize(protocol)
  @protocol = protocol
end

Instance Method Details

#authenticate(passwd, scramble) {|String| ... } ⇒ Mysql::Packet

Parameters:

  • passwd (String)
  • scramble (String)

Yields:

  • (String)

    hashed password

Returns:



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
# File 'lib/mysql/authenticator/caching_sha2_password.rb', line 21

def authenticate(passwd, scramble)
  yield hash_password(passwd, scramble)
  pkt = @protocol.read
  data = pkt.to_s
  if data.size == 2 && data[0] == "\x01"
    case data[1]
    when "\x03"  # fast_auth_success
      # OK
    when "\x04"  # perform_full_authentication
      if @protocol.client_flags & CLIENT_SSL != 0
        @protocol.write passwd+"\0"
      elsif !@protocol.get_server_public_key
        raise ClientError::AuthPluginErr, 'Authentication requires secure connection'
      else
        @protocol.write "\2"  # request public key
        pkt = @protocol.read
        pkt.utiny # skip
        pubkey = pkt.to_s
        hash = (passwd+"\0").unpack("C*").zip(scramble.unpack("C*")).map{|a, b| a ^ b}.pack("C*")
        enc = OpenSSL::PKey::RSA.new(pubkey).public_encrypt(hash, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
        @protocol.write enc
      end
    else
      raise ClientError, "invalid auth reply packet: #{data.inspect}"
    end
    pkt = @protocol.read
  end
  return pkt
end

#hash_password(passwd, scramble) ⇒ String

Returns hashed password.

Parameters:

  • passwd (String)
  • scramble (String)

Returns:

  • (String)

    hashed password



54
55
56
57
58
59
60
# File 'lib/mysql/authenticator/caching_sha2_password.rb', line 54

def hash_password(passwd, scramble)
  return '' if passwd.nil? or passwd.empty?
  hash1 = Digest::SHA256.digest(passwd)
  hash2 = Digest::SHA256.digest(hash1)
  hash3 = Digest::SHA256.digest(hash2 + scramble)
  hash1.unpack("C*").zip(hash3.unpack("C*")).map{|a, b| a ^ b}.pack("C*")
end

#nameString

Returns:

  • (String)


13
14
15
# File 'lib/mysql/authenticator/caching_sha2_password.rb', line 13

def name
  'caching_sha2_password'
end