You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2010/01/12 23:20:32 UTC

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

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(<<X/binary>>, <<Y/binary>>) ->
+    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.