diff options
author | Joan Touzet <joant@atypical.net> | 2018-07-18 12:31:42 -0400 |
---|---|---|
committer | Joan Touzet <wohali@users.noreply.github.com> | 2018-07-18 14:31:35 -0400 |
commit | 7597abf850870bb63e115ec004106b403a9be42c (patch) | |
tree | aa43f5285658cf4719e207f2495f4e48d050df71 | |
parent | 91f84f3314b4e54767e43f57d46a3724b6e69db6 (diff) | |
download | couchdb-7597abf850870bb63e115ec004106b403a9be42c.tar.gz |
Revert "Add bcrypt hashing option"
This reverts commit 817b2b6f5f0883092df60c1ec8ec7ec6d6094a23.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | LICENSE | 117 | ||||
-rw-r--r-- | NOTICE | 7 | ||||
-rw-r--r-- | rebar.config.script | 7 | ||||
-rw-r--r-- | rel/overlay/etc/default.ini | 3 | ||||
-rw-r--r-- | rel/reltool.config | 2 | ||||
-rw-r--r-- | src/couch/src/couch.app.src | 1 | ||||
-rw-r--r-- | src/couch/src/couch.erl | 1 | ||||
-rw-r--r-- | src/couch/src/couch_auth_cache.erl | 7 | ||||
-rw-r--r-- | src/couch/src/couch_httpd_auth.erl | 12 | ||||
-rw-r--r-- | src/couch/src/couch_passwords.erl | 19 | ||||
-rw-r--r-- | src/couch/src/couch_users_db.erl | 10 | ||||
-rw-r--r-- | src/couch/test/couch_passwords_tests.erl | 42 | ||||
-rw-r--r-- | test/javascript/tests/users_db_security.js | 160 |
14 files changed, 22 insertions, 367 deletions
diff --git a/.gitignore b/.gitignore index a1cba1e0b..088303039 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ share/server/main.js share/www src/b64url/ src/bear/ -src/bcrypt/ src/config/ src/couch/priv/couch_js/config.h src/couch/priv/couchjs @@ -2158,123 +2158,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -The Erlang code is subject to this license: - -%% Copyright (c) 2011 Hunter Morris <hunter.morris@smarkets.com> - -%% Permission to use, copy, modify, and distribute this software for any -%% purpose with or without fee is hereby granted, provided that the above -%% copyright notice and this permission notice appear in all copies. - -%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -The underlying blowfish code is derived from OpenBSD libc and is -subject to the following license: - -/* - * Blowfish block cipher for OpenBSD - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> - * All rights reserved. - * - * Implementation advice by David Mazieres <dm@lcs.mit.edu>. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -The underlying bcrypt (hashing) code is derived from OpenBSD libc and is -subject to the following license: - -/* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -The asynchronous queue code (c_src/async_queue.c and -c_src/async_queue.h) is from the esnappy project, copyright 2011 -Konstantin V. Sorokin. It is subject to the following license: - -Copyright (c) 2011 Konstantin V. Sorokin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - For the src/hyper component: The MIT License (MIT) @@ -178,13 +178,6 @@ This product also includes the following third-party components: Copyright (c) 2015 Twitter, Inc. -* erlang-bcrypt - - Erlang code: Copyright (c) 2011 Hunter Morris <hunter.morris@smarkets.com> - - Blowfish block cipher & bcrypt (hashing) code for OpenBSD, Copyright - 1997 Niels Provos <provos@physnet.uni-hamburg.de> - - The asynchronous queue code (c_src/async_queue.c and c_src/async_queue.h) - is from the esnappy project, copyright 2011 Konstantin V. Sorokin. - * hyper Copyright (c) 2014 Game Analytics ApS diff --git a/rebar.config.script b/rebar.config.script index b873018a6..072d29fc8 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -65,10 +65,7 @@ DepDescs = [ {ibrowse, "ibrowse", {tag, "CouchDB-4.0.1"}}, {jiffy, "jiffy", {tag, "CouchDB-0.14.11-2"}}, {mochiweb, "mochiweb", {tag, "v2.17.0"}}, -{meck, "meck", {tag, "0.8.8"}}, -{bcrypt, {url, "https://github.com/apache/couchdb-erlang-bcrypt"}, - {tag, "1.0.2"}}, -{triq, "triq", {tag, "v1.2.0"}} +{meck, "meck", {tag, "0.8.8"}} ], @@ -105,7 +102,7 @@ AddConfig = [ {plt_location, local}, {plt_location, COUCHDB_ROOT}, {plt_extra_apps, [ - asn1, bcrypt, compiler, crypto, inets, kernel, os_mon, runtime_tools, + asn1, compiler, crypto, inets, kernel, os_mon, runtime_tools, sasl, setup, ssl, stdlib, syntax_tools, xmerl]}, {warnings, [unmatched_returns, error_handling, race_conditions]}]}, {post_hooks, [{compile, "escript support/build_js.escript"}]} diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index 77f0e387c..aa9763ce0 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -206,8 +206,7 @@ require_valid_user = false timeout = 600 ; number of seconds before automatic logout auth_cache_size = 50 ; size is number of cache entries allow_persistent_cookies = false ; set to true to allow persistent cookies -iterations = 10 ; iterations for PBKDF2 password hashing -log_rounds = 10 ; 2^log_rounds iterations for Bcrypt password hashing +iterations = 10 ; iterations for password hashing ; min_iterations = 1 ; max_iterations = 1000000000 ; password_scheme = pbkdf2 diff --git a/rel/reltool.config b/rel/reltool.config index 5e86d9643..2c55d0900 100644 --- a/rel/reltool.config +++ b/rel/reltool.config @@ -15,7 +15,6 @@ {rel, "couchdb", "2.2.0", [ %% stdlib asn1, - bcrypt, compiler, crypto, inets, @@ -68,7 +67,6 @@ %% stdlib {app, asn1, [{incl_cond, include}]}, - {app, bcrypt, [{incl_cond, include}]}, {app, compiler, [{incl_cond, include}]}, {app, crypto, [{incl_cond, include}]}, {app, inets, [{incl_cond, include}]}, diff --git a/src/couch/src/couch.app.src b/src/couch/src/couch.app.src index cf5cee6b8..6af213624 100644 --- a/src/couch/src/couch.app.src +++ b/src/couch/src/couch.app.src @@ -31,7 +31,6 @@ kernel, stdlib, crypto, - bcrypt, sasl, inets, ssl, diff --git a/src/couch/src/couch.erl b/src/couch/src/couch.erl index f956b4b3d..fd5c9e101 100644 --- a/src/couch/src/couch.erl +++ b/src/couch/src/couch.erl @@ -21,7 +21,6 @@ deps() -> inets, os_mon, crypto, - bcrypt, public_key, ssl, ibrowse, diff --git a/src/couch/src/couch_auth_cache.erl b/src/couch/src/couch_auth_cache.erl index 425cce010..157b0902e 100644 --- a/src/couch/src/couch_auth_cache.erl +++ b/src/couch/src/couch_auth_cache.erl @@ -92,8 +92,6 @@ get_admin(UserName) when is_list(UserName) -> "-pbkdf2-" ++ HashedPwdSaltAndIterations -> [HashedPwd, Salt, Iterations] = string:tokens(HashedPwdSaltAndIterations, ","), make_admin_doc(HashedPwd, Salt, Iterations); - "-bcrypt-" ++ HashedPwd -> - make_admin_doc(HashedPwd); _Else -> nil end. @@ -111,11 +109,6 @@ make_admin_doc(DerivedKey, Salt, Iterations) -> {<<"password_scheme">>, <<"pbkdf2">>}, {<<"derived_key">>, ?l2b(DerivedKey)}]. -make_admin_doc(DerivedKey) -> - [{<<"roles">>, [<<"_admin">>]}, - {<<"password_scheme">>, <<"bcrypt">>}, - {<<"derived_key">>, ?l2b(DerivedKey)}]. - get_from_cache(UserName) -> exec_if_auth_db( fun(_AuthDb) -> diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl index 74cbe5a08..6ac7b75af 100644 --- a/src/couch/src/couch_httpd_auth.erl +++ b/src/couch/src/couch_httpd_auth.erl @@ -309,12 +309,7 @@ handle_session_req(#httpd{method='POST', mochi_req=MochiReq}=Req, AuthModule) -> Secret = ?l2b(ensure_cookie_auth_secret()), UserSalt = couch_util:get_value(<<"salt">>, UserProps), CurrentTime = make_cookie_time(), - Cookie = case UserSalt of - undefined -> - cookie_auth_cookie(Req, ?b2l(UserName), <<Secret/binary>>, CurrentTime); - _ -> - cookie_auth_cookie(Req, ?b2l(UserName), <<Secret/binary, UserSalt/binary>>, CurrentTime) - end, + Cookie = cookie_auth_cookie(Req, ?b2l(UserName), <<Secret/binary, UserSalt/binary>>, CurrentTime), % TODO document the "next" feature in Futon {Code, Headers} = case couch_httpd:qs_value(Req, "next", nil) of nil -> @@ -406,10 +401,7 @@ authenticate(Pass, UserProps) -> Iterations = couch_util:get_value(<<"iterations">>, UserProps, 10000), verify_iterations(Iterations), {couch_passwords:pbkdf2(Pass, UserSalt, Iterations), - couch_util:get_value(<<"derived_key">>, UserProps, nil)}; - <<"bcrypt">> -> - UserHash = couch_util:get_value(<<"derived_key">>, UserProps, nil), - {couch_passwords:bcrypt(Pass, UserHash), UserHash} + couch_util:get_value(<<"derived_key">>, UserProps, nil)} end, couch_passwords:verify(PasswordHash, ExpectedHash). diff --git a/src/couch/src/couch_passwords.erl b/src/couch/src/couch_passwords.erl index 77e136144..baf78f5d5 100644 --- a/src/couch/src/couch_passwords.erl +++ b/src/couch/src/couch_passwords.erl @@ -12,7 +12,7 @@ -module(couch_passwords). --export([simple/2, pbkdf2/3, pbkdf2/4, bcrypt/2, verify/2]). +-export([simple/2, pbkdf2/3, pbkdf2/4, verify/2]). -export([hash_admin_password/1, get_unhashed_admins/0]). -include_lib("couch/include/couch_db.hrl"). @@ -51,10 +51,7 @@ hash_admin_password("pbkdf2", ClearPassword) -> Salt ,list_to_integer(Iterations)), ?l2b("-pbkdf2-" ++ ?b2l(DerivedKey) ++ "," ++ ?b2l(Salt) ++ "," - ++ Iterations); -hash_admin_password("bcrypt", ClearPassword) -> - LogRounds = list_to_integer(config:get("couch_httpd_auth", "log_rounds", "10")), - ?l2b("-bcrypt-" ++ couch_passwords:bcrypt(couch_util:to_binary(ClearPassword), LogRounds)). + ++ Iterations). -spec get_unhashed_admins() -> list(). get_unhashed_admins() -> @@ -63,8 +60,6 @@ get_unhashed_admins() -> false; % already hashed ({_User, "-pbkdf2-" ++ _}) -> false; % already hashed - ({_User, "-bcrypt-" ++ _}) -> - false; % already hashed ({_User, _ClearPassword}) -> true end, @@ -128,16 +123,6 @@ pbkdf2(Password, Salt, Iterations, BlockIndex, Iteration, Prev, Acc) -> pbkdf2(Password, Salt, Iterations, BlockIndex, Iteration + 1, Next, crypto:exor(Next, Acc)). -%% Define the bcrypt functions to hash a password --spec bcrypt(binary(), binary()) -> binary(); - (binary(), integer()) -> binary(). -bcrypt(Password, Salt) when is_binary(Salt) -> - {ok, Hash} = bcrypt:hashpw(Password, Salt), - list_to_binary(Hash); -bcrypt(Password, LogRounds) when is_integer(LogRounds) -> - {ok, Salt} = bcrypt:gen_salt(LogRounds), - bcrypt(Password, list_to_binary(Salt)). - %% verify two lists for equality without short-circuits to avoid timing attacks. -spec verify(string(), string(), integer()) -> boolean(). verify([X|RestX], [Y|RestY], Result) -> diff --git a/src/couch/src/couch_users_db.erl b/src/couch/src/couch_users_db.erl index dd6d3208c..c7b41f1fc 100644 --- a/src/couch/src/couch_users_db.erl +++ b/src/couch/src/couch_users_db.erl @@ -23,7 +23,6 @@ -define(SIMPLE, <<"simple">>). -define(PASSWORD_SHA, <<"password_sha">>). -define(PBKDF2, <<"pbkdf2">>). --define(BCRYPT, <<"bcrypt">>). -define(ITERATIONS, <<"iterations">>). -define(SALT, <<"salt">>). -define(replace(L, K, V), lists:keystore(K, 1, L, {K, V})). @@ -60,7 +59,7 @@ before_doc_update(Doc, Db) -> % newDoc.salt = salt % newDoc.password = null save_doc(#doc{body={Body}} = Doc) -> - %% Support all schemes to smooth migration from legacy scheme + %% Support both schemes to smooth migration from legacy scheme Scheme = config:get("couch_httpd_auth", "password_scheme", "pbkdf2"), case {couch_util:get_value(?PASSWORD, Body), Scheme} of {null, _} -> % server admins don't have a user-db password entry @@ -85,13 +84,6 @@ save_doc(#doc{body={Body}} = Doc) -> Body3 = ?replace(Body2, ?SALT, Salt), Body4 = proplists:delete(?PASSWORD, Body3), Doc#doc{body={Body4}}; - {ClearPassword, "bcrypt"} -> - LogRounds = list_to_integer(config:get("couch_httpd_auth", "log_rounds", "10")), - DerivedKey = couch_passwords:bcrypt(ClearPassword, LogRounds), - Body0 = ?replace(Body, ?PASSWORD_SCHEME, ?BCRYPT), - Body1 = ?replace(Body0, ?DERIVED_KEY, DerivedKey), - Body2 = proplists:delete(?PASSWORD, Body1), - Doc#doc{body={Body2}}; {_ClearPassword, Scheme} -> couch_log:error("[couch_httpd_auth] password_scheme value of '~p' is invalid.", [Scheme]), throw({forbidden, "Server cannot hash passwords at this time."}) diff --git a/src/couch/test/couch_passwords_tests.erl b/src/couch/test/couch_passwords_tests.erl index c624dba5b..dea6d6b7b 100644 --- a/src/couch/test/couch_passwords_tests.erl +++ b/src/couch/test/couch_passwords_tests.erl @@ -14,6 +14,7 @@ -include_lib("couch/include/couch_eunit.hrl"). + pbkdf2_test_()-> {"PBKDF2", [ @@ -51,44 +52,3 @@ pbkdf2_test_()-> {ok, <<"eefe3d61cd4da4e4e9945b3d6ba2158c2634e984">>}, couch_passwords:pbkdf2(<<"password">>, <<"salt">>, 16777216, 20) )}}]}. - - - -setup() -> - test_util:start(?MODULE, [bcrypt]). - -teardown(Ctx)-> - test_util:stop(Ctx). - -bcrypt_test_() -> - { - "Bcrypt", - { - foreach, - fun setup/0, fun teardown/1, - [ - {timeout, 1, fun bcrypt_logRounds_4/0}, - {timeout, 5, fun bcrypt_logRounds_12/0}, - {timeout, 180, fun bcrypt_logRounds_18/0}, - {timeout, 5, fun bcrypt_null_byte/0} - - ] - } - }. - -bcrypt_logRounds_4() -> - bcrypt_assert_equal(<<"password">>, 4). - -bcrypt_logRounds_12() -> - bcrypt_assert_equal(<<"password">>, 12). - -bcrypt_logRounds_18() -> - bcrypt_assert_equal(<<"password">>, 18). - -bcrypt_null_byte() -> - bcrypt_assert_equal(<<"passw\0rd">>, 12). - -bcrypt_assert_equal(Password, Rounds) when is_integer(Rounds) -> - HashPass = couch_passwords:bcrypt(Password, Rounds), - ReHashPass = couch_passwords:bcrypt(Password, HashPass), - ?_assertEqual(HashPass, ReHashPass). diff --git a/test/javascript/tests/users_db_security.js b/test/javascript/tests/users_db_security.js index 4cc154edd..1db6c14c5 100644 --- a/test/javascript/tests/users_db_security.js +++ b/test/javascript/tests/users_db_security.js @@ -15,8 +15,6 @@ couchTests.users_db_security = function(debug) { var usersDb = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ } - var passwordSchemes = ['pbkdf2', 'bcrypt']; - if (debug) debugger; var loginUser = function(username) { @@ -88,7 +86,7 @@ couchTests.users_db_security = function(debug) { } }; - var testFun = function(scheme, derivedKeyTest, saltTest) + var testFun = function() { // _users db @@ -107,13 +105,11 @@ couchTests.users_db_security = function(debug) { // jan's gonna be admin as he's the first user TEquals(true, usersDb.save(userDoc).ok, "should save document"); - wait(5000); + wait(5000) userDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris"); TEquals(undefined, userDoc.password, "password field should be null 1"); - TEquals(scheme, userDoc.password_scheme, "password_scheme should be " + scheme); - derivedKeyTest(userDoc.derived_key); - saltTest(userDoc.salt); - + TEquals(40, userDoc.derived_key.length, "derived_key should exist"); + TEquals(32, userDoc.salt.length, "salt should exist"); // create server admin @@ -145,13 +141,10 @@ couchTests.users_db_security = function(debug) { var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jan"); TEquals(undefined, jchrisDoc.password, "password field should be null 2"); - TEquals(scheme, jchrisDoc.password_scheme, "password_scheme should be " + scheme); - derivedKeyTest(jchrisDoc.derived_key); - saltTest(jchrisDoc.salt); + TEquals(40, jchrisDoc.derived_key.length, "derived_key should exist"); + TEquals(32, jchrisDoc.salt.length, "salt should exist"); - if(userDoc.salt || jchrisDoc.salt) { - TEquals(true, userDoc.salt != jchrisDoc.salt, "should have new salt"); - } + TEquals(true, userDoc.salt != jchrisDoc.salt, "should have new salt"); TEquals(true, userDoc.derived_key != jchrisDoc.derived_key, "should have new derived_key"); @@ -234,7 +227,7 @@ couchTests.users_db_security = function(debug) { TEquals("forbidden", e.error, "non-admins can't read design docs"); } - // admin should be able to read _list + // admin shold be able to read _list var listPath = ddoc["_id"] + "/_list/names/test"; var result = request_as(usersDb, listPath, "jan"); var lines = result.responseText.split("\n"); @@ -380,140 +373,14 @@ couchTests.users_db_security = function(debug) { }); }; - var derivedKeyTests = { - pbkdf2: function(derived_key) { - TEquals(40, derived_key.length, "derived_key should exist"); - }, - bcrypt: function(derived_key) { - TEquals(60, derived_key.length, "derived_key should exist"); - } - }; - var saltTests = { - pbkdf2: function(salt) { - TEquals(32, salt.length, "salt should exist"); - }, - bcrypt: function(salt) { - TEquals(undefined, salt, "salt should not exist"); - } - }; - passwordSchemes.forEach(function(scheme){ - run_on_modified_server( - [{ - section: "couch_httpd_auth", - key: "iterations", value: "1" - }, { - section: "couch_httpd_auth", - key: "password_scheme", value: scheme - }, { - section: "admins", - key: "jan", value: "apple" - }], - function() { - try { - testFun(scheme, derivedKeyTests[scheme], saltTests[scheme]); - } catch (e) { - throw(e) - } finally { - CouchDB.login("jan", "apple"); - usersDb.deleteDb(); // cleanup - waitForSuccess(function() { - var req = CouchDB.request("GET", db_name); - if (req.status == 404) { - return true - } - throw({}); - }, 'usersDb.deleteDb') - - usersDb.createDb(); - waitForSuccess(function() { - var req = CouchDB.request("GET", db_name); - if (req.status == 200) { - return true - } - throw({}); - }, 'usersDb.creteDb') - } - } - ); - }); - - var testFunUpdatePasswordScheme = function() { - var userDocs = { - jchris: { - _id: "org.couchdb.user:jchris", - type: "user", - name: "jchris", - password: "mp3", - roles: [] - }, - fdmanana: { - _id: "org.couchdb.user:fdmanana", - type: "user", - name: "fdmanana", - password: "foobar", - roles: [] - } - }; - - // create new user (has pbkdf2 hash) - TEquals(true, usersDb.save(userDocs.jchris).ok, "should save document"); - wait(5000); - var userDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris"); - TEquals(undefined, userDoc.password, "password field should be null 1"); - TEquals("pbkdf2", userDoc.password_scheme, "password_scheme should be pbkdf2"); - derivedKeyTests.pbkdf2(userDoc.derived_key); - saltTests.pbkdf2(userDoc.salt); - - // change scheme to bcrypt - CouchDB.login("jan", "apple"); - var xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme", { - body : JSON.stringify("bcrypt"), - headers: {"X-Couch-Persist": "false"} - }); - TEquals(200, xhr.status); - xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme"); - var scheme = JSON.parse(xhr.responseText); - TEquals("bcrypt", scheme); - - // create new user (has bcrypt hash) - TEquals(true, usersDb.save(userDocs.fdmanana).ok, "should save document"); - wait(5000); - userDoc = open_as(usersDb, "org.couchdb.user:fdmanana", "fdmanana"); - TEquals(undefined, userDoc.password, "password field should be null 1"); - TEquals("bcrypt", userDoc.password_scheme, "password_scheme should be bcrypt"); - derivedKeyTests.bcrypt(userDoc.derived_key); - saltTests.bcrypt(userDoc.salt); - - // test that both users can still log in - TEquals(true, CouchDB.login(userDocs.jchris.name, userDocs.jchris.password).ok); - TEquals(true, CouchDB.login(userDocs.fdmanana.name, userDocs.fdmanana.password).ok); - - // change scheme back to pbkdf2 - CouchDB.login("jan", "apple"); - var xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme", { - body : JSON.stringify("pbkdf2"), - headers: {"X-Couch-Persist": "false"} - }); - TEquals(200, xhr.status); - xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/password_scheme"); - var scheme = JSON.parse(xhr.responseText); - TEquals("pbkdf2", scheme); - - // test that both users can still log in - TEquals(true, CouchDB.login(userDocs.jchris.name, userDocs.jchris.password).ok); - TEquals(true, CouchDB.login(userDocs.fdmanana.name, userDocs.fdmanana.password).ok); - }; run_on_modified_server( - [{ - section: "couch_httpd_auth", - key: "iterations", value: "1" - }, { - section: "admins", - key: "jan", value: "apple" - }], + [{section: "couch_httpd_auth", + key: "iterations", value: "1"}, + {section: "admins", + key: "jan", value: "apple"}], function() { try { - testFunUpdatePasswordScheme(); + testFun(); } finally { CouchDB.login("jan", "apple"); usersDb.deleteDb(); // cleanup @@ -535,6 +402,5 @@ couchTests.users_db_security = function(debug) { } } ); - CouchDB.logout(); }; |