Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support alternate hash algorithms #14

Merged
merged 4 commits into from Jan 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions etc/couchdb/default.d/browserid.ini
Expand Up @@ -5,6 +5,7 @@
enabled = false
verify_url = https://verifier.login.persona.org/verify
audience = http://example.com
; hash_algorithm = <choose one of: none, hmac, gravatar. If hmac, set hash_secret below >
; hash_secret = <long crypto-random string, e.g. from https://api.wordpress.org/secret-key/1.1/>

[httpd_global_handlers]
Expand Down
4 changes: 4 additions & 0 deletions priv/main.js
Expand Up @@ -172,6 +172,10 @@ $.couch.browserid.login(function(ev, er, userCtx) {
widget.unbind('click');

var iurl = 'https://www.gravatar.com/avatar/' + Crypto.MD5($.trim(email).toLowerCase()) + "?s=32";
if (email.indexOf('@') === -1) {
// it is probably already a gravatar hash
iurl = 'https://www.gravatar.com/avatar/' + email + "?s=32";
}
var gravatar_img = $("<img>").attr('src', iurl);
gravatar_img.appendTo($("#browserid .picture"));

Expand Down
30 changes: 28 additions & 2 deletions src/couch_httpd_browserid.erl
Expand Up @@ -23,15 +23,22 @@
%% * Possibly auto-create user doc in browserid_authentication_handler/1
%% * Do something sane with providers other than browserid.org

% hash_if_required looks for hash_secret in browserid section of config
% hash_if_required looks for hash_algorithm in browserid section of config
% if not found, default to hmac to keep backward compat.
hash_if_required(Email) -> ok
, Algorithm = couch_config:get("browserid", "hash_algorithm", "hmac")
, ?LOG_DEBUG("Algorithm chosen: ~s", [Algorithm])
, hash_if_required(Algorithm, Email).

% hash_if_required (hmac) looks for hash_secret in browserid section of config
% If it exist and isn't an empty string, uses it as hmac key according to code from
% http://stackoverflow.com/questions/4193543/erlang-calculating-hmac-sha1-example/4202361#4202361
% If missing or empty (i.e. admin doesn't want to hash usernames), simply returns the argument
% (this is the default)
% If you use hash_secret, make sure the string is long enough and cryptographically random
% Tip: use one of the strings from https://api.wordpress.org/secret-key/1.1/ :)

hash_if_required(Email) -> ok
hash_if_required("hmac", Email) -> ok
, Hashkey = couch_config:get("browserid", "hash_secret", undefined)
, case Hashkey
of undefined -> ok
Expand All @@ -40,8 +47,27 @@ hash_if_required(Email) -> ok
, <<Mac:160/integer>> = crypto:sha_mac(?l2b(Key),Email)
, ?l2b(lists:flatten(io_lib:format("~40.16.0b", [Mac])))
end
;

% hash_if_required (gravatar) looks provides the same hasing as gravatar,
% and is based on the code from https://github.com/kanso/gravatar/blob/master/gravatar.js#L17
hash_if_required("gravatar", Email) -> ok
, Trim = re:replace(Email, "(^\\s+)|(\\s+$)", "", [global,{return,list}])
, Lower = string:to_lower(Trim)
, <<Md5:128/integer>> = crypto:md5(Lower)
, ?l2b(lists:flatten(io_lib:format("~32.16.0b", [Md5])))
;

hash_if_required("none", Email) -> Email;

% hash_if_required (_) returns the Email, and warns user.
hash_if_required(_, Email) -> ok
, Message = <<"No hash_algorithm specified. Not hashing email address.">>
, ?LOG_ERROR("~s", [Message])
, hash_if_required(none, Email)
.


handle_id_req(#httpd{method='GET'}=Req) -> ok
, case code:priv_dir(browserid_couchdb)
of {error, bad_name} -> ok
Expand Down