]> granicus.if.org Git - ejabberd/commitdiff
Apply SASLprep before storing/converting passwords
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 12 Feb 2017 07:06:30 +0000 (10:06 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 12 Feb 2017 07:06:30 +0000 (10:06 +0300)
Fixes #996 and #1295

src/ejabberd_auth_mnesia.erl
src/ejabberd_auth_riak.erl
src/ejabberd_auth_sql.erl

index 1c565d485a2ea7ae610a47f4f7304389d42c63b2..a4e9c1f89b238297d130bdda57ddafb73384ef89 100644 (file)
@@ -143,9 +143,12 @@ check_password(User, AuthzId, Server, Password, Digest,
 set_password(User, Server, Password) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
+    LPassword = jid:resourceprep(Password),
     US = {LUser, LServer},
     if (LUser == error) or (LServer == error) ->
           {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
           F = fun () ->
                       Password2 = case is_scrammed() and is_binary(Password)
@@ -167,9 +170,12 @@ try_register(User, Server, PasswordList) ->
       iolist_to_binary(PasswordList);
       true -> PasswordList
     end,
+    LPassword = jid:resourceprep(Password),
     US = {LUser, LServer},
     if (LUser == error) or (LServer == error) ->
           {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
           F = fun () ->
                       case mnesia:read({passwd, US}) of
@@ -441,9 +447,21 @@ scram_passwords() ->
     ?INFO_MSG("Converting the stored passwords into "
              "SCRAM bits",
              []),
-    Fun = fun (#passwd{password = Password} = P) ->
-                 Scram = password_to_scram(Password),
-                 P#passwd{password = Scram}
+    Fun = fun (#passwd{us = {U, S}, password = Password} = P)
+               when is_binary(Password) ->
+                 case jid:resourceprep(Password) of
+                     error ->
+                         ?ERROR_MSG(
+                            "SASLprep failed for "
+                            "password of user ~s@~s",
+                            [U, S]),
+                         P;
+                     _ ->
+                         Scram = password_to_scram(Password),
+                         P#passwd{password = Scram}
+                 end;
+             (P) ->
+                 P
          end,
     Fields = record_info(fields, passwd),
     mnesia:transform_table(passwd, Fun, Fields).
@@ -465,13 +483,18 @@ password_to_scram(Password, IterationCount) ->
           iterationcount = IterationCount}.
 
 is_password_scram_valid(Password, Scram) ->
-    IterationCount = Scram#scram.iterationcount,
-    Salt = jlib:decode_base64(Scram#scram.salt),
-    SaltedPassword = scram:salted_password(Password, Salt,
-                                          IterationCount),
-    StoredKey =
-       scram:stored_key(scram:client_key(SaltedPassword)),
-    jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
+    case jid:resourceprep(Password) of
+       error ->
+           false;
+       _ ->
+           IterationCount = Scram#scram.iterationcount,
+           Salt = jlib:decode_base64(Scram#scram.salt),
+           SaltedPassword = scram:salted_password(Password, Salt,
+                                                  IterationCount),
+           StoredKey =
+               scram:stored_key(scram:client_key(SaltedPassword)),
+           jlib:decode_base64(Scram#scram.storedkey) == StoredKey
+    end.
 
 export(_Server) ->
     [{passwd,
index 16468dea1deaebf68d4fe1e46122fc0d6e483ad8..67f2126becddc187c12a5d70e0c9a6d35eaa9440 100644 (file)
@@ -120,9 +120,12 @@ check_password(User, AuthzId, Server, Password, Digest,
 set_password(User, Server, Password) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
+    LPassword = jid:resourceprep(Password),
     US = {LUser, LServer},
     if (LUser == error) or (LServer == error) ->
           {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
             Password2 = case is_scrammed() and is_binary(Password)
                         of
@@ -141,9 +144,12 @@ try_register(User, Server, PasswordList) ->
       iolist_to_binary(PasswordList);
       true -> PasswordList
     end,
+    LPassword = jid:resourceprep(Password),
     US = {LUser, LServer},
     if (LUser == error) or (LServer == error) ->
           {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
             case ejabberd_riak:get(passwd, passwd_schema(), US) of
                 {error, notfound} ->
@@ -284,13 +290,18 @@ password_to_scram(Password, IterationCount) ->
           iterationcount = IterationCount}.
 
 is_password_scram_valid(Password, Scram) ->
-    IterationCount = Scram#scram.iterationcount,
-    Salt = jlib:decode_base64(Scram#scram.salt),
-    SaltedPassword = scram:salted_password(Password, Salt,
-                                          IterationCount),
-    StoredKey =
-       scram:stored_key(scram:client_key(SaltedPassword)),
-    jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
+    case jid:resourceprep(Password) of
+       error ->
+           false;
+       _ ->
+           IterationCount = Scram#scram.iterationcount,
+           Salt = jlib:decode_base64(Scram#scram.salt),
+           SaltedPassword = scram:salted_password(Password, Salt,
+                                                  IterationCount),
+           StoredKey =
+               scram:stored_key(scram:client_key(SaltedPassword)),
+           jlib:decode_base64(Scram#scram.storedkey) == StoredKey
+    end.
 
 export(_Server) ->
     [{passwd,
index 313e9faea85b6e50473f999ff9402f19cf32ac04..4228b3345cd9ba2fa9c4a4f7af9fbd94c3c455b8 100644 (file)
@@ -159,10 +159,13 @@ check_password(User, AuthzId, Server, Password, Digest,
 set_password(User, Server, Password) ->
     LServer = jid:nameprep(Server),
     LUser = jid:nodeprep(User),
+    LPassword = jid:resourceprep(Password),
     if (LUser == error) or (LServer == error) ->
             {error, invalid_jid};
        (LUser == <<>>) or (LServer == <<>>) ->
             {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
             case is_scrammed() of
                 true ->
@@ -193,10 +196,13 @@ set_password(User, Server, Password) ->
 try_register(User, Server, Password) ->
     LServer = jid:nameprep(Server),
     LUser = jid:nodeprep(User),
+    LPassword = jid:resourceprep(Password),
     if (LUser == error) or (LServer == error) ->
             {error, invalid_jid};
        (LUser == <<>>) or (LServer == <<>>) ->
             {error, invalid_jid};
+       LPassword == error ->
+          {error, invalid_password};
        true ->
             case is_scrammed() of
                 true ->
@@ -427,13 +433,18 @@ is_password_scram_valid_stored(Password, Scram, _, _) ->
     is_password_scram_valid(Password, Scram).
 
 is_password_scram_valid(Password, Scram) ->
-    IterationCount = Scram#scram.iterationcount,
-    Salt = jlib:decode_base64(Scram#scram.salt),
-    SaltedPassword = scram:salted_password(Password, Salt,
-                                          IterationCount),
-    StoredKey =
-       scram:stored_key(scram:client_key(SaltedPassword)),
-    jlib:decode_base64(Scram#scram.storedkey) == StoredKey.
+    case jid:resourceprep(Password) of
+       error ->
+           false;
+       _ ->
+           IterationCount = Scram#scram.iterationcount,
+           Salt = jlib:decode_base64(Scram#scram.salt),
+           SaltedPassword = scram:salted_password(Password, Salt,
+                                                  IterationCount),
+           StoredKey =
+               scram:stored_key(scram:client_key(SaltedPassword)),
+           jlib:decode_base64(Scram#scram.storedkey) == StoredKey
+    end.
 
 -define(BATCH_SIZE, 1000).
 
@@ -466,14 +477,21 @@ convert_to_scram(Server) ->
                             {selected, Rs} ->
                                 lists:foreach(
                                   fun({LUser, Password}) ->
-                                          Scram = password_to_scram(Password),
-                                          set_password_scram_t(
-                                            LUser,
-                                            Scram#scram.storedkey,
-                                            Scram#scram.serverkey,
-                                            Scram#scram.salt,
-                                            Scram#scram.iterationcount
-                                           )
+                                         case jid:resourceprep(Password) of
+                                             error ->
+                                                 ?ERROR_MSG(
+                                                    "SASLprep failed for "
+                                                    "password of user ~s@~s",
+                                                    [LUser, LServer]);
+                                             _ ->
+                                                 Scram = password_to_scram(Password),
+                                                 set_password_scram_t(
+                                                   LUser,
+                                                   Scram#scram.storedkey,
+                                                   Scram#scram.serverkey,
+                                                   Scram#scram.salt,
+                                                   Scram#scram.iterationcount)
+                                         end
                                   end, Rs),
                                 continue;
                             Err -> {bad_reply, Err}