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

Converting to scram throws error due to a newline character in password #996

Closed
cdroege opened this issue Mar 10, 2016 · 6 comments
Closed

Comments

@cdroege
Copy link
Contributor

cdroege commented Mar 10, 2016

I am trying to convert a user database in mysql to the scram format. For this I have a database, that has the correct table coloumns for scram. I start the conversion via ejabberdctl debug:

ejabberd_auth_odbc:convert_to_scram(<<"localhost">>).
{aborted,{badarg,[{crypto,sha_mac_n,
                          [error,
                           << [REMOVED]
                             >>,
                           20],
                          []},
                  {scram,hi,3,[{file,"src/scram.erl"},{line,73}]},
                  {ejabberd_auth_odbc,password_to_scram,2,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,396}]},
                  {ejabberd_auth_odbc,'-convert_to_scram/1-fun-0-',1,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,450}]},
                  {lists,foreach,2,[{file,"lists.erl"},{line,1337}]},
                  {ejabberd_auth_odbc,'-convert_to_scram/1-fun-1-',0,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,447}]},
                  {ejabberd_odbc,outer_transaction,3,
                                 [{file,"src/ejabberd_odbc.erl"},{line,445}]},
                  {ejabberd_odbc,run_sql_cmd,4,
                                 [{file,"src/ejabberd_odbc.erl"},{line,382}]}]}}

This error happens after it converted the first hundreds of users. It has a problem with passwords that contain a newline character ("\n"). There are a few dozen users with such a password.

Here is a test case with an empty database:

$ ejabberdctl register test localhost "bla
"
User test@localhost successfully registered

[add the missing table coloumns to the users table here]

$ echo 'select * from ejabberd.users where username="test";' | mysql -u root
username    password    created_at  serverkey   salt    iterationcount
test bla\n  2016-03-10 14:33:12         0

$ ejabberdctl debug
[...]
(ejabberd@localhost)1> ejabberd_auth_odbc:convert_to_scram(<<"localhost">>).
{aborted,{badarg,[{crypto,sha_mac_n,
                          [error,
                           <<224,198,212,158,107,84,199,123,219,64,207,103,61,94,82,
                             49,0,0,0,...>>,
                           20],
                          []},
                  {scram,hi,3,[{file,"src/scram.erl"},{line,73}]},
                  {ejabberd_auth_odbc,password_to_scram,2,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,396}]},
                  {ejabberd_auth_odbc,'-convert_to_scram/1-fun-0-',1,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,450}]},
                  {lists,foreach,2,[{file,"lists.erl"},{line,1337}]},
                  {ejabberd_auth_odbc,'-convert_to_scram/1-fun-1-',0,
                                      [{file,"src/ejabberd_auth_odbc.erl"},{line,447}]},
                  {ejabberd_odbc,outer_transaction,3,
                                 [{file,"src/ejabberd_odbc.erl"},{line,445}]},
                  {ejabberd_odbc,run_sql_cmd,4,
                                 [{file,"src/ejabberd_odbc.erl"},{line,382}]}]}}

I tested this with ejabberd 16.02 and 16.01.

@cdroege cdroege changed the title Converting to scram throws error Converting to scram throws error due to an newline character in password Mar 10, 2016
@cdroege cdroege changed the title Converting to scram throws error due to an newline character in password Converting to scram throws error due to a newline character in password Mar 10, 2016
@mremond mremond added this to the ejabberd 16.03 milestone Mar 10, 2016
@mremond mremond removed this from the ejabberd 16.03 milestone Mar 10, 2016
@cdroege
Copy link
Contributor Author

cdroege commented Mar 11, 2016

The "error" comes from jid:resourceprep here:

salted_password(Password, Salt, IterationCount) ->
    hi(jid:resourceprep(Password), Salt, IterationCount).

The password should be normalized with saslprep and not resourceprep. Saslprep seems to support newline characters, if I read the RFC correctly. The stringprep module does not support saslprep.

@cdroege
Copy link
Contributor Author

cdroege commented Mar 11, 2016

Nevermind. Saslprep does not allow newline characters.

@badlop
Copy link
Member

badlop commented Mar 14, 2016

In summary, what's the result of your findings?
A) does XMPP allow newline characters in passwords (and then ejabberd has a problem)?
B) Or newline characters are not allowed (and then ejabberd is correct)?

@cdroege
Copy link
Contributor Author

cdroege commented Mar 14, 2016

Both. It depends on the SASL mechanism.

From the PLAIN RFC:

   The presented authentication identity and password strings, as well
   as the database authentication identity and password strings, are to
   be prepared before being used in the verification process.  The
   [SASLPrep] profile of the [StringPrep] algorithm is the RECOMMENDED
   preparation algorithm.  The SASLprep preparation algorithm is
   recommended to improve the likelihood that comparisons behave in an
   expected manner.  The SASLprep preparation algorithm is not mandatory
   so as to allow the server to employ other preparation algorithms
   (including none) when appropriate.  For instance, use of a different
   preparation algorithm may be necessary for the server to interoperate
   with an external system.

From the SCRAM RFC:

[...]
     SaltedPassword  := Hi(Normalize(password), salt, i)
[...]
 o  Normalize(str): Apply the SASLprep profile [RFC4013] of the
      "stringprep" algorithm [RFC3454] as the normalization algorithm to
      a UTF-8 [RFC3629] encoded "str".  

SASLprep does not allow control characters such as newline characters.

Ejabberd does not use a preparation algorithm when using PLAIN (or when registering an account), but uses it for SCRAM. This causes a problem when converting the database and I found another problem, that I tested:

  1. User registers an account with a newline character
  2. Server saves this password as plaintext
  3. Users client tries to use SCRAM authentication
  4. Server responds with not-authorized, because the saved password does not pass the jid:resourceprep(Password) check (resourceprep and SASLprep are very similiar, so this is OK)
  5. PLAIN authentication by the clients works

There probably should always be a jid:resourceprep check, when a password is used, but this is a problem for existing password databases, because they already contain a newline character. But it should not be a problem adding this check to the registration of new users.

Note: I dont have much experience reading RFCs.

@zinid
Copy link
Contributor

zinid commented Feb 12, 2017

This issue still requires some fixes, see #1295

@lock
Copy link

lock bot commented Jun 11, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants