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



38
39
40
41
# File 'lib/mongo/auth/scram_conversation_base.rb', line 38

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



44
45
46
# File 'lib/mongo/auth/scram_conversation_base.rb', line 44

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



52
53
54
# File 'lib/mongo/auth/scram_conversation_base.rb', line 52

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



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

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



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

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



100
101
102
103
# File 'lib/mongo/auth/scram_conversation_base.rb', line 100

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

#server_verified?true | fase

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 | fase)

    Whether the server’s signature was verified.

See Also:

Since:

  • 2.0.0



59
60
61
# File 'lib/mongo/auth/scram_conversation_base.rb', line 59

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



126
127
128
# File 'lib/mongo/auth/scram_conversation_base.rb', line 126

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