Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 53109 invoked from network); 12 Jan 2010 22:20:54 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 12 Jan 2010 22:20:54 -0000 Received: (qmail 92305 invoked by uid 500); 12 Jan 2010 22:20:54 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 92253 invoked by uid 500); 12 Jan 2010 22:20:54 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 92244 invoked by uid 99); 12 Jan 2010 22:20:54 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Jan 2010 22:20:54 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Jan 2010 22:20:53 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id F0F2F238890A; Tue, 12 Jan 2010 22:20:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r898552 - in /couchdb/branches/0.10.x: src/couchdb/couch_httpd_auth.erl src/couchdb/couch_util.erl src/erlang-oauth/oauth_hmac_sha1.erl src/erlang-oauth/oauth_plaintext.erl test/etap/040-util.t Date: Tue, 12 Jan 2010 22:20:32 -0000 To: commits@couchdb.apache.org From: jasondavies@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100112222032.F0F2F238890A@eris.apache.org> Author: jasondavies Date: Tue Jan 12 22:20:32 2010 New Revision: 898552 URL: http://svn.apache.org/viewvc?rev=898552&view=rev Log: Backport trunk r898477: Add utility for verifying hashes. Modified: couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl couchdb/branches/0.10.x/src/couchdb/couch_util.erl couchdb/branches/0.10.x/src/erlang-oauth/oauth_hmac_sha1.erl couchdb/branches/0.10.x/src/erlang-oauth/oauth_plaintext.erl couchdb/branches/0.10.x/test/etap/040-util.t Modified: couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl?rev=898552&r1=898551&r2=898552&view=diff ============================================================================== --- couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl (original) +++ couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl Tue Jan 12 22:20:32 2010 @@ -232,14 +232,18 @@ Timeout = to_int(couch_config:get("couch_httpd_auth", "timeout", 600)), ?LOG_DEBUG("timeout ~p", [Timeout]), case (catch erlang:list_to_integer(TimeStr, 16)) of - TimeStamp when CurrentTime < TimeStamp + Timeout - andalso ExpectedHash == Hash -> - TimeLeft = TimeStamp + Timeout - CurrentTime, - ?LOG_DEBUG("Successful cookie auth as: ~p", [User]), - Req#httpd{user_ctx=#user_ctx{ - name=?l2b(User), - roles=proplists:get_value(<<"roles">>, Result, []) - }, auth={FullSecret, TimeLeft < Timeout*0.9}}; + TimeStamp when CurrentTime < TimeStamp + Timeout -> + case couch_util:verify(ExpectedHash, Hash) of + true -> + TimeLeft = TimeStamp + Timeout - CurrentTime, + ?LOG_DEBUG("Successful cookie auth as: ~p", [User]), + Req#httpd{user_ctx=#user_ctx{ + name=?l2b(User), + roles=proplists:get_value(<<"roles">>, Result, []) + }, auth={FullSecret, TimeLeft < Timeout*0.9}}; + _Else -> + nil + end; _Else -> nil end @@ -301,8 +305,9 @@ end, UserSalt = proplists:get_value(<<"salt">>, User, <<>>), PasswordHash = hash_password(Password, UserSalt), - case proplists:get_value(<<"password_sha">>, User, nil) of - ExpectedHash when ExpectedHash == PasswordHash -> + ExpectedHash = proplists:get_value(<<"password_sha">>, User, nil), + case couch_util:verify(ExpectedHash, PasswordHash) of + true -> Secret = ?l2b(couch_config:get("couch_httpd_auth", "secret", nil)), {NowMS, NowS, _} = erlang:now(), CurrentTime = NowMS * 1000000 + NowS, @@ -448,10 +453,9 @@ _Else -> OldPasswordHash = hash_password(OldPassword1, UserSalt), ?LOG_DEBUG("~p == ~p", [CurrentPasswordHash, OldPasswordHash]), - Hash1 = case CurrentPasswordHash of - ExpectedHash when ExpectedHash == OldPasswordHash -> - H = hash_password(Password, UserSalt), - H; + Hash1 = case couch_util:verify(CurrentPasswordHash, OldPasswordHash) of + true -> + hash_password(Password, UserSalt); _ -> throw({forbidden, <<"Old password is incorrect.">>}) end, Modified: couchdb/branches/0.10.x/src/couchdb/couch_util.erl URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/src/couchdb/couch_util.erl?rev=898552&r1=898551&r2=898552&view=diff ============================================================================== --- couchdb/branches/0.10.x/src/couchdb/couch_util.erl (original) +++ couchdb/branches/0.10.x/src/couchdb/couch_util.erl Tue Jan 12 22:20:32 2010 @@ -20,6 +20,7 @@ to_hex/1,parse_term/1, dict_find/3]). -export([file_read_size/1, get_nested_json_value/2, json_user_ctx/1]). -export([to_binary/1, to_list/1, url_encode/1]). +-export([verify/2]). -include("couch_db.hrl"). -include_lib("kernel/include/file.hrl"). @@ -394,4 +395,20 @@ end end; url_encode([]) -> - []. \ No newline at end of file + []. + +verify([X|RestX], [Y|RestY], Result) -> + verify(RestX, RestY, (X bxor Y) bor Result); +verify([], [], Result) -> + Result == 0. + +verify(<>, <>) -> + verify(?b2l(X), ?b2l(Y)); +verify(X, Y) when is_list(X) and is_list(Y) -> + case length(X) == length(Y) of + true -> + verify(X, Y, 0); + false -> + false + end; +verify(_X, _Y) -> false. Modified: couchdb/branches/0.10.x/src/erlang-oauth/oauth_hmac_sha1.erl URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/src/erlang-oauth/oauth_hmac_sha1.erl?rev=898552&r1=898551&r2=898552&view=diff ============================================================================== --- couchdb/branches/0.10.x/src/erlang-oauth/oauth_hmac_sha1.erl (original) +++ couchdb/branches/0.10.x/src/erlang-oauth/oauth_hmac_sha1.erl Tue Jan 12 22:20:32 2010 @@ -8,4 +8,4 @@ base64:encode_to_string(crypto:sha_mac(Key, BaseString)). verify(Signature, BaseString, CS, TS) -> - Signature =:= signature(BaseString, CS, TS). + couch_util:verify(signature(BaseString, CS, TS), Signature). Modified: couchdb/branches/0.10.x/src/erlang-oauth/oauth_plaintext.erl URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/src/erlang-oauth/oauth_plaintext.erl?rev=898552&r1=898551&r2=898552&view=diff ============================================================================== --- couchdb/branches/0.10.x/src/erlang-oauth/oauth_plaintext.erl (original) +++ couchdb/branches/0.10.x/src/erlang-oauth/oauth_plaintext.erl Tue Jan 12 22:20:32 2010 @@ -7,4 +7,4 @@ oauth_uri:calate("&", [CS, TS]). verify(Signature, CS, TS) -> - Signature =:= signature(CS, TS). + couch_util:verify(signature(CS, TS), Signature). Modified: couchdb/branches/0.10.x/test/etap/040-util.t URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/test/etap/040-util.t?rev=898552&r1=898551&r2=898552&view=diff ============================================================================== --- couchdb/branches/0.10.x/test/etap/040-util.t (original) +++ couchdb/branches/0.10.x/test/etap/040-util.t Tue Jan 12 22:20:32 2010 @@ -17,7 +17,7 @@ test_util:init_code_path(), application:start(crypto), - etap:plan(12), + etap:plan(17), case (catch test()) of ok -> etap:end_tests(); @@ -91,4 +91,16 @@ etap:ok(not couch_util:should_flush(), "Checking to flush invokes GC."), + % verify + etap:is(true, couch_util:verify("It4Vooya", "It4Vooya"), + "String comparison."), + etap:is(false, couch_util:verify("It4VooyaX", "It4Vooya"), + "String comparison (unequal lengths)."), + etap:is(true, couch_util:verify(<<"ahBase3r">>, <<"ahBase3r">>), + "Binary comparison."), + etap:is(false, couch_util:verify(<<"ahBase3rX">>, <<"ahBase3r">>), + "Binary comparison (unequal lengths)."), + etap:is(false, couch_util:verify(nil, <<"ahBase3r">>), + "Binary comparison with atom."), + ok.