Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCRAM Auth Procedure #78

Closed
LetThereBeDwight opened this issue Jan 7, 2021 · 2 comments · Fixed by #79
Closed

SCRAM Auth Procedure #78

LetThereBeDwight opened this issue Jan 7, 2021 · 2 comments · Fixed by #79
Assignees

Comments

@LetThereBeDwight
Copy link
Contributor

LetThereBeDwight commented Jan 7, 2021

So I'm trying to connect to AWS DocumentDB and ran into an issue with the SCRAM Auth. I know the docs say that X509 is required but I do not think that is any longer true as AWS DocDB does support SCRAM now. When running the challenge, the reply comes back successful after the first message, but when verifying the signature from that response, the signature for method second looks like this:

  defp second(%{"conversationId" => conversation_id, "payload" => payload, "done" => false}, signature) do
    params = parse_payload(payload)
    ^signature = params["v"] |> Base.decode64!
    [saslContinue: 1, conversationId: conversation_id, payload: %BSON.Binary{binary: ""}]
  end

The reply (from AWS at least...when using a local Mongo deployment the reply is of the above form), has the parameter done set to true rather than false. As a quick patch I removed that field from the pattern matching and it works just fine, the signature matches, and the connection holds.

So this is more question than issue(but kind of both), and I've got something of a lack of knowledge on the subject - but what is the reason to pattern match on that parameter? Is there some motivation there to ensure that done is false, and if so, should there be a secondary function that matches on true and handles the handshake in a different way?

There seems to be a similar issue discussed in the original parent library here: elixir-mongo/mongodb#273, in which they just remove it from the pattern matching, though I can't find any discussion of the original motivation/intent here.

@zookzook zookzook self-assigned this Jan 8, 2021
@zookzook
Copy link
Owner

zookzook commented Jan 8, 2021

Good catch. The scram auth was introduced in 2015. At the moment I cannot say what exactly the attribute "done" means. But I guess, there are three steps and in the last step the attribute "done" is matched against true:

    result =
      with {:ok, %{"ok" => ok} = reply} when ok == 1 <- Utils.command(-3, message, s),
           {message, signature} = first(reply, first_bare, username, password, nonce, digest),
           {:ok, %{"ok" => ok} = reply} when ok == 1 <- Utils.command(-4, message, s),
           message = second(reply, signature),
           {:ok, %{"ok" => ok} = reply} when ok == 1 <- Utils.command(-5, message, s),
           do: final(reply)

and here:

  defp second(%{"conversationId" => conversation_id, "payload" => payload, "done" => false}, signature) do
    params = parse_payload(payload)
    ^signature = params["v"] |> Base.decode64!
    [saslContinue: 1, conversationId: conversation_id, payload: %BSON.Binary{binary: ""}]
  end

  defp final(%{"conversationId" => _, "payload" => %BSON.Binary{binary: ""}, "done" => true}) do
    :ok
  end

So, maybe the code is outdated and needs to be fixed.

@LetThereBeDwight
Copy link
Contributor Author

LetThereBeDwight commented Jan 8, 2021

Yea looking at the parent lib it looks like the final is okay - we probably shouldn't expect a "done" variable to be anything other than true after the final response. Everyone over there seemed to be of the mind that the change to second was warranted, and that was all I needed to get it to connect with AWS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants