Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Support alternate hash algorithms #14

Merged
merged 4 commits into from

2 participants

@ryanramage

This PR allows for alternate hash algorithms to be used to obscure the email address. It is backwards compatible if one is not specified, and will use hmac if a hash_secret is provided in the .ini file.

It adds gravatar support so the email address will be hashed the same way a gravatar email will be, and be compatible with this implementation.

Usage

Add the following to your .ini file

hash_algorithm = gravatar

The hash_algorithm can be one of: none, hmac, gravatar. If hmac is selected, a hash_secret must be provided as before.

This PR has passed the test suite :) I have yet to fully test using build_couchdb as build_couchdb is not recognizing any plugins.

@ryanramage

OK, I have tested this in build_couchdb and it works for no hash_algorithm, and hash_algorithm = hmac, gravatar, and none. Should be ok to pull with a review.

@jhs jhs merged commit a8fa6a9 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
1  etc/couchdb/default.d/browserid.ini
@@ -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]
View
4 priv/main.js
@@ -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"));
View
30 src/couch_httpd_browserid.erl
@@ -23,7 +23,14 @@
%% * 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
@@ -31,7 +38,7 @@
% 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
@@ -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
Something went wrong with that request. Please try again.