Class: Mongo::Auth::ScramConversationBase Private

Inherits:
SaslConversationBase show all
Defined in:
lib/mongo/auth/scram_conversation_base.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Defines common behavior around authentication conversations between the client and the server.

Since:

  • 2.0.0

Constant Summary collapse

MIN_ITER_COUNT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The minimum iteration count for SCRAM-SHA-1 and SCRAM-SHA-256.

Since:

  • 2.0.0

4096

Constants inherited from SaslConversationBase

Mongo::Auth::SaslConversationBase::CLIENT_CONTINUE_MESSAGE, Mongo::Auth::SaslConversationBase::CLIENT_FIRST_MESSAGE

Instance Attribute Summary collapse

Attributes inherited from ConversationBase

#connection, #user

Instance Method Summary collapse

Methods inherited from SaslConversationBase

#start

Methods inherited from ConversationBase

#build_message, #validate_external_auth_source

Constructor Details

#initialize(user, connection, client_nonce: nil) ⇒ ScramConversationBase

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create the new conversation.

Parameters:

  • user (Auth::User)

    The user to converse about.

  • client_nonce (String | nil) (defaults to: nil)

    The client nonce to use. If this conversation is created for a connection that performed speculative authentication, this client nonce must be equal to the client nonce used for speculative authentication; otherwise, the client nonce must not be specified.

Since:

  • 2.0.0



35
36
37
38
# File 'lib/mongo/auth/scram_conversation_base.rb', line 35

def initialize(user, connection, client_nonce: nil)
  super
  @client_nonce = client_nonce || SecureRandom.base64
end

Instance Attribute Details

#client_nonceString (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns client_nonce The client nonce.

Returns:

  • (String)

    client_nonce The client nonce.

Since:

  • 2.0.0



41
42
43
# File 'lib/mongo/auth/scram_conversation_base.rb', line 41

def client_nonce
  @client_nonce
end

#idInteger (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the id of the conversation.

Examples:

Get the id of the conversation.

conversation.id

Returns:

  • (Integer)

    The conversation id.

Since:

  • 2.0.0



49
50
51
# File 'lib/mongo/auth/scram_conversation_base.rb', line 49

def id
  @id
end

Instance Method Details

#continue(reply_document, connection) ⇒ Protocol::Message

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Continue the SCRAM conversation. This sends the client final message to the server after setting the reply from the previous server communication.

Parameters:

  • reply_document (BSON::Document)

    The reply document of the previous message.

  • connection (Server::Connection)

    The connection being authenticated.

Returns:

Since:

  • 2.0.0



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mongo/auth/scram_conversation_base.rb', line 70

def continue(reply_document, connection)
  @id = reply_document['conversationId']
  payload_data = reply_document['payload'].data
  parsed_data = parse_payload(payload_data)
  @server_nonce = parsed_data.fetch('r')
  @salt = Base64.strict_decode64(parsed_data.fetch('s'))
  @iterations = parsed_data.fetch('i').to_i.tap do |i|
    if i < MIN_ITER_COUNT
      raise Error::InsufficientIterationCount.new(
        Error::InsufficientIterationCount.message(MIN_ITER_COUNT, i)
      )
    end
  end
  @auth_message = "#{first_bare},#{payload_data},#{without_proof}"

  validate_server_nonce!

  selector = CLIENT_CONTINUE_MESSAGE.merge(
    payload: client_final_message,
    conversationId: id
  )
  build_message(connection, user.auth_source, selector)
end

#finalize(connection) ⇒ Protocol::Message

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Finalize the SCRAM conversation. This is meant to be iterated until the provided reply indicates the conversation is finished.

Parameters:

Returns:

Since:

  • 2.0.0



109
110
111
112
113
114
115
# File 'lib/mongo/auth/scram_conversation_base.rb', line 109

def finalize(connection)
  selector = CLIENT_CONTINUE_MESSAGE.merge(
    payload: client_empty_message,
    conversationId: id
  )
  build_message(connection, user.auth_source, selector)
end

#process_continue_response(reply_document) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Processes the second response from the server.

Parameters:

  • reply_document (BSON::Document)

    The reply document of the continue response.

Since:

  • 2.0.0



98
99
100
101
# File 'lib/mongo/auth/scram_conversation_base.rb', line 98

def process_continue_response(reply_document)
  payload_data = parse_payload(reply_document['payload'].data)
  check_server_signature(payload_data)
end

#server_verified?true | false

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether the client verified the ServerSignature from the server.

Returns:

  • (true | false)

    Whether the server’s signature was verified.

See Also:

Since:

  • 2.0.0



56
57
58
# File 'lib/mongo/auth/scram_conversation_base.rb', line 56

def server_verified?
  !!@server_verified
end

#speculative_auth_documentHash | nil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the hash to provide to the server in the handshake as value of the speculativeAuthenticate key.

If the auth mechanism does not support speculative authentication, this method returns nil.

Returns:

  • (Hash | nil)

    Speculative authentication document.

Since:

  • 2.0.0



124
125
126
# File 'lib/mongo/auth/scram_conversation_base.rb', line 124

def speculative_auth_document
  client_first_document.merge(db: user.auth_source)
end