You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2023/10/24 11:04:02 UTC
[couchdb] 08/09: remove all password derivation fields before adding back the new ones
This is an automated email from the ASF dual-hosted git repository.
rnewson pushed a commit to branch decouple_offline_hash_strength_from_online
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 1f33d6a0bd849d6e0cbfd3955426bcc2bfe8bc37
Author: Robert Newson <rn...@apache.org>
AuthorDate: Mon Oct 23 18:32:22 2023 +0100
remove all password derivation fields before adding back the new ones
---
src/couch/src/couch_users_db.erl | 48 +++++++++++++++++++++++++++-------------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/src/couch/src/couch_users_db.erl b/src/couch/src/couch_users_db.erl
index a32591d99..e3b914969 100644
--- a/src/couch/src/couch_users_db.erl
+++ b/src/couch/src/couch_users_db.erl
@@ -27,7 +27,6 @@
-define(PRESERVE_SALT, <<"preserve_salt">>).
-define(ITERATIONS, <<"iterations">>).
-define(SALT, <<"salt">>).
--define(replace(L, K, V), lists:keystore(K, 1, L, {K, V})).
-define(REQUIREMENT_ERROR, "Password does not conform to requirements.").
-define(PASSWORD_SERVER_ERROR, "Server cannot hash passwords at this time.").
@@ -90,12 +89,14 @@ save_doc(#doc{body = {Body}} = Doc) ->
{ClearPassword, "simple"} ->
ok = validate_password(ClearPassword),
PasswordSha = couch_passwords:simple(ClearPassword, Salt),
- Body0 = ?replace(Body, ?PASSWORD_SCHEME, ?SIMPLE),
- Body1 = ?replace(Body0, ?SALT, Salt),
- Body2 = ?replace(Body1, ?PASSWORD_SHA, PasswordSha),
- Body3 = proplists:delete(?PRESERVE_SALT, Body2),
- Body4 = proplists:delete(?PASSWORD, Body3),
- Doc#doc{body = {Body4}};
+ Body0 = remove_password_fields(Body),
+ Body1 = [
+ {?PASSWORD_SCHEME, ?SIMPLE},
+ {?SALT, Salt},
+ {?PASSWORD_SHA, PasswordSha}
+ | Body0
+ ],
+ Doc#doc{body = {Body1}};
{ClearPassword, "pbkdf2"} ->
ok = validate_password(ClearPassword),
PRF = chttpd_util:get_chttpd_auth_config("pbkdf2_prf", "sha256"),
@@ -105,19 +106,36 @@ save_doc(#doc{body = {Body}} = Doc) ->
DerivedKey = couch_passwords:pbkdf2(
list_to_existing_atom(PRF), ClearPassword, Salt, Iterations
),
- Body0 = ?replace(Body, ?PASSWORD_SCHEME, ?PBKDF2),
- Body1 = ?replace(Body0, ?PBKDF2_PRF, ?l2b(PRF)),
- Body2 = ?replace(Body1, ?ITERATIONS, Iterations),
- Body3 = ?replace(Body2, ?DERIVED_KEY, DerivedKey),
- Body4 = ?replace(Body3, ?SALT, Salt),
- Body5 = proplists:delete(?PRESERVE_SALT, Body4),
- Body6 = proplists:delete(?PASSWORD, Body5),
- Doc#doc{body = {Body6}};
+ Body0 = remove_password_fields(Body),
+ Body1 = [
+ {?PASSWORD_SCHEME, ?PBKDF2},
+ {?PBKDF2_PRF, ?l2b(PRF)},
+ {?SALT, Salt},
+ {?ITERATIONS, Iterations},
+ {?DERIVED_KEY, DerivedKey}
+ | Body0
+ ],
+ Doc#doc{body = {Body1}};
{_ClearPassword, Scheme} ->
couch_log:error("[couch_httpd_auth] password_scheme value of '~p' is invalid.", [Scheme]),
throw({forbidden, ?PASSWORD_SERVER_ERROR})
end.
+remove_password_fields(Props) ->
+ lists:filter(fun not_password_field/1, Props).
+
+not_password_field({Key, _Value}) ->
+ not lists:member(Key, [
+ ?DERIVED_KEY,
+ ?ITERATIONS,
+ ?PASSWORD,
+ ?PASSWORD_SCHEME,
+ ?PASSWORD_SHA,
+ ?PRESERVE_SALT,
+ ?PBKDF2_PRF,
+ ?SALT
+ ]).
+
% Validate if a new password matches all RegExp in the password_regexp setting.
% Throws if not.
% In this function the [couch_httpd_auth] password_regexp config is parsed.