Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E3FDFE01A for ; Thu, 6 Dec 2012 12:15:23 +0000 (UTC) Received: (qmail 15132 invoked by uid 500); 6 Dec 2012 12:15:23 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 15100 invoked by uid 500); 6 Dec 2012 12:15:23 -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 15088 invoked by uid 99); 6 Dec 2012 12:15:23 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Dec 2012 12:15:23 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 21823819792; Thu, 6 Dec 2012 12:15:23 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jan@apache.org To: commits@couchdb.apache.org X-Mailer: ASF-Git Admin Mailer Subject: git commit: update erlang-oauth to 1.3.0 Message-Id: <20121206121523.21823819792@tyr.zones.apache.org> Date: Thu, 6 Dec 2012 12:15:23 +0000 (UTC) Updated Branches: refs/heads/1597-update-erlang-oauth-1-3-0 ba4cab37b -> d74e93c90 (forced update) update erlang-oauth to 1.3.0 Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/d74e93c9 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/d74e93c9 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/d74e93c9 Branch: refs/heads/1597-update-erlang-oauth-1-3-0 Commit: d74e93c904fc1b55a2f83bb6e7362e602cd72b16 Parents: b9af7ea Author: Jan Lehnardt Authored: Mon Nov 12 21:11:39 2012 +0100 Committer: Jan Lehnardt Committed: Thu Dec 6 13:15:08 2012 +0100 ---------------------------------------------------------------------- LICENSE | 2 +- NOTICE | 4 +- .../src/couch_replicator_httpc.erl | 4 +- src/couchdb/couch_httpd_oauth.erl | 2 +- src/erlang-oauth/Makefile.am | 15 +- src/erlang-oauth/oauth.erl | 328 ++++++++++++--- src/erlang-oauth/oauth_hmac_sha1.erl | 11 - src/erlang-oauth/oauth_http.erl | 22 - src/erlang-oauth/oauth_plaintext.erl | 10 - src/erlang-oauth/oauth_rsa_sha1.erl | 30 -- src/erlang-oauth/oauth_unix.erl | 16 - src/erlang-oauth/oauth_uri.erl | 100 ----- test/etap/160-vhosts.t | 4 +- 13 files changed, 278 insertions(+), 270 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/LICENSE ---------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index be511b1..f65c452 100644 --- a/LICENSE +++ b/LICENSE @@ -350,7 +350,7 @@ For the src/ibrowse component: For the src/erlang-oauth component: - Copyright (c) 2008-2009 Tim Fletcher + Copyright the authors and contributors. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/NOTICE ---------------------------------------------------------------------- diff --git a/NOTICE b/NOTICE index ef3ff9e..6608656 100644 --- a/NOTICE +++ b/NOTICE @@ -38,9 +38,9 @@ This product also includes the following third-party components: Copyright 2009, Chandrashekhar Mullaparthi - * Erlang OAuth (http://github.com/tim/erlang-oauth/tree/master) + * Erlang OAuth (http://github.com/tim/erlang-oauth) - Copyright 2009, Tim Fletcher + Copyright 2012, the authors and contributors * ETap (http://github.com/ngerakines/etap/) http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/couch_replicator/src/couch_replicator_httpc.erl ---------------------------------------------------------------------- diff --git a/src/couch_replicator/src/couch_replicator_httpc.erl b/src/couch_replicator/src/couch_replicator_httpc.erl index 8773383..c6cf321 100644 --- a/src/couch_replicator/src/couch_replicator_httpc.erl +++ b/src/couch_replicator/src/couch_replicator_httpc.erl @@ -244,11 +244,11 @@ oauth_header(#httpdb{url = BaseUrl, oauth = OAuth}, ConnParams) -> head -> "HEAD" end, QSL = get_value(qs, ConnParams, []), - OAuthParams = oauth:signed_params(Method, + OAuthParams = oauth:sign(Method, BaseUrl ++ get_value(path, ConnParams, []), QSL, Consumer, OAuth#oauth.token, OAuth#oauth.token_secret) -- QSL, [{"Authorization", - "OAuth " ++ oauth_uri:params_to_header_string(OAuthParams)}]. + "OAuth " ++ oauth:header_params_encode(OAuthParams)}]. do_redirect(Worker, Code, Headers, #httpdb{url = Url} = HttpDb, Params, Cb) -> http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/couchdb/couch_httpd_oauth.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd_oauth.erl b/src/couchdb/couch_httpd_oauth.erl index 90990e6..2094c08 100644 --- a/src/couchdb/couch_httpd_oauth.erl +++ b/src/couchdb/couch_httpd_oauth.erl @@ -189,7 +189,7 @@ serve_oauth(#httpd{mochi_req=MochiReq}=Req, Fun, FailSilently) -> _ -> "" end end, - HeaderParams = oauth_uri:params_from_header_string(AuthHeader), + HeaderParams = oauth:header_params_decode(AuthHeader), %Realm = couch_util:get_value("realm", HeaderParams), % get requested path http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/Makefile.am ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/Makefile.am b/src/erlang-oauth/Makefile.am index 48b7648..a334677 100644 --- a/src/erlang-oauth/Makefile.am +++ b/src/erlang-oauth/Makefile.am @@ -14,25 +14,14 @@ oauthebindir = $(localerlanglibdir)/erlang-oauth/ebin oauth_file_collection = \ oauth.app.in \ - oauth.erl \ - oauth_hmac_sha1.erl \ - oauth_http.erl \ - oauth_plaintext.erl \ - oauth_rsa_sha1.erl \ - oauth_unix.erl \ - oauth_uri.erl + oauth.erl # Removed oauth_rsa_sha1.beam until we require R12B5 or # we add a ./configure option to enable it. oauthebin_make_generated_file_list = \ oauth.app \ - oauth.beam \ - oauth_hmac_sha1.beam \ - oauth_http.beam \ - oauth_plaintext.beam \ - oauth_unix.beam \ - oauth_uri.beam + oauth.beam oauthebin_DATA = \ $(oauthebin_make_generated_file_list) http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth.erl b/src/erlang-oauth/oauth.erl index 866655c..e75d5fd 100644 --- a/src/erlang-oauth/oauth.erl +++ b/src/erlang-oauth/oauth.erl @@ -1,34 +1,54 @@ -module(oauth). --export( - [ get/5 - , header/1 - , post/5 - , signature/5 - , signature_base_string/3 - , signed_params/6 - , token/1 - , token_secret/1 - , uri/2 - , verify/6 - ]). +-export([get/3, get/5, get/6, post/3, post/5, post/6, put/6, put/7, uri/2, header/1, + sign/6, params_decode/1, token/1, token_secret/1, verify/6]). +-export([plaintext_signature/2, hmac_sha1_signature/5, + hmac_sha1_signature/3, rsa_sha1_signature/4, rsa_sha1_signature/2, + signature_base_string/3, params_encode/1]). + +-export([plaintext_verify/3, hmac_sha1_verify/6, hmac_sha1_verify/4, + rsa_sha1_verify/5, rsa_sha1_verify/3]). + +-export([header_params_encode/1, header_params_decode/1, + uri_params_encode/1, uri_params_decode/1]). + +-include_lib("public_key/include/public_key.hrl"). + +get(URL, ExtraParams, Consumer) -> + get(URL, ExtraParams, Consumer, "", ""). get(URL, ExtraParams, Consumer, Token, TokenSecret) -> - SignedParams = signed_params("GET", URL, ExtraParams, Consumer, Token, TokenSecret), - oauth_http:get(uri(URL, SignedParams)). + get(URL, ExtraParams, Consumer, Token, TokenSecret, []). + +get(URL, ExtraParams, Consumer, Token, TokenSecret, HttpcOptions) -> + SignedParams = sign("GET", URL, ExtraParams, Consumer, Token, TokenSecret), + http_request(get, {uri(URL, SignedParams), []}, HttpcOptions). + +post(URL, ExtraParams, Consumer) -> + post(URL, ExtraParams, Consumer, "", ""). post(URL, ExtraParams, Consumer, Token, TokenSecret) -> - SignedParams = signed_params("POST", URL, ExtraParams, Consumer, Token, TokenSecret), - oauth_http:post(URL, oauth_uri:params_to_string(SignedParams)). + post(URL, ExtraParams, Consumer, Token, TokenSecret, []). + +post(URL, ExtraParams, Consumer, Token, TokenSecret, HttpcOptions) -> + SignedParams = sign("POST", URL, ExtraParams, Consumer, Token, TokenSecret), + http_request(post, {URL, [], "application/x-www-form-urlencoded", uri_params_encode(SignedParams)}, HttpcOptions). + +put(URL, ExtraParams, {ContentType, Body}, Consumer, Token, TokenSecret) -> + put(URL, ExtraParams, {ContentType, Body}, Consumer, Token, TokenSecret, []). + +put(URL, ExtraParams, {ContentType, Body}, Consumer, Token, TokenSecret, HttpcOptions) -> + SignedParams = sign("PUT", URL, ExtraParams, Consumer, Token, TokenSecret), + http_request(put, {uri(URL, SignedParams), [], ContentType, Body}, HttpcOptions). uri(Base, []) -> Base; uri(Base, Params) -> - lists:concat([Base, "?", oauth_uri:params_to_string(Params)]). + lists:concat([Base, "?", uri_params_encode(Params)]). header(Params) -> - {"Authorization", "OAuth " ++ oauth_uri:params_to_header_string(Params)}. + {"Authorization", "OAuth " ++ header_params_encode(Params)}. token(Params) -> proplists:get_value("oauth_token", Params). @@ -36,49 +56,28 @@ token(Params) -> token_secret(Params) -> proplists:get_value("oauth_token_secret", Params). -verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) -> - case signature_method(Consumer) of - plaintext -> - oauth_plaintext:verify(Signature, consumer_secret(Consumer), TokenSecret); - hmac_sha1 -> - BaseString = signature_base_string(HttpMethod, URL, Params), - oauth_hmac_sha1:verify(Signature, BaseString, consumer_secret(Consumer), TokenSecret); - rsa_sha1 -> - BaseString = signature_base_string(HttpMethod, URL, Params), - oauth_rsa_sha1:verify(Signature, BaseString, consumer_secret(Consumer)) - end. +consumer_key(_Consumer={Key, _, _}) -> + Key. -signed_params(HttpMethod, URL, ExtraParams, Consumer, Token, TokenSecret) -> - Params = token_param(Token, params(Consumer, ExtraParams)), - [{"oauth_signature", signature(HttpMethod, URL, Params, Consumer, TokenSecret)}|Params]. +consumer_secret(_Consumer={_, Secret, _}) -> + Secret. -signature(HttpMethod, URL, Params, Consumer, TokenSecret) -> - case signature_method(Consumer) of - plaintext -> - oauth_plaintext:signature(consumer_secret(Consumer), TokenSecret); - hmac_sha1 -> - BaseString = signature_base_string(HttpMethod, URL, Params), - oauth_hmac_sha1:signature(BaseString, consumer_secret(Consumer), TokenSecret); - rsa_sha1 -> - BaseString = signature_base_string(HttpMethod, URL, Params), - oauth_rsa_sha1:signature(BaseString, consumer_secret(Consumer)) - end. +signature_method(_Consumer={_, _, Method}) -> + Method. -signature_base_string(HttpMethod, URL, Params) -> - NormalizedURL = oauth_uri:normalize(URL), - NormalizedParams = oauth_uri:params_to_string(lists:sort(Params)), - oauth_uri:calate("&", [HttpMethod, NormalizedURL, NormalizedParams]). +sign(HttpMethod, URL, Params, Consumer, Token, TokenSecret) -> + SignatureParams = signature_params(Consumer, Params, Token), + Signature = signature(HttpMethod, URL, SignatureParams, Consumer, TokenSecret), + [{"oauth_signature", Signature} | SignatureParams]. -token_param("", Params) -> - Params; -token_param(Token, Params) -> - [{"oauth_token", Token}|Params]. +signature_params(Consumer, Params, "") -> + signature_params(Consumer, Params); +signature_params(Consumer, Params, Token) -> + signature_params(Consumer, [{"oauth_token", Token} | Params]). -params(Consumer, Params) -> +signature_params(Consumer, Params) -> + Timestamp = unix_timestamp(), Nonce = base64:encode_to_string(crypto:rand_bytes(32)), % cf. ruby-oauth - params(Consumer, oauth_unix:timestamp(), Nonce, Params). - -params(Consumer, Timestamp, Nonce, Params) -> [ {"oauth_version", "1.0"} , {"oauth_nonce", Nonce} , {"oauth_timestamp", integer_to_list(Timestamp)} @@ -87,6 +86,26 @@ params(Consumer, Timestamp, Nonce, Params) -> | Params ]. +verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) -> + case signature_method(Consumer) of + plaintext -> + plaintext_verify(Signature, Consumer, TokenSecret); + hmac_sha1 -> + hmac_sha1_verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret); + rsa_sha1 -> + rsa_sha1_verify(Signature, HttpMethod, URL, Params, Consumer) + end. + +signature(HttpMethod, URL, Params, Consumer, TokenSecret) -> + case signature_method(Consumer) of + plaintext -> + plaintext_signature(Consumer, TokenSecret); + hmac_sha1 -> + hmac_sha1_signature(HttpMethod, URL, Params, Consumer, TokenSecret); + rsa_sha1 -> + rsa_sha1_signature(HttpMethod, URL, Params, Consumer) + end. + signature_method_string(Consumer) -> case signature_method(Consumer) of plaintext -> @@ -97,11 +116,200 @@ signature_method_string(Consumer) -> "RSA-SHA1" end. -signature_method(_Consumer={_, _, Method}) -> - Method. +plaintext_signature(Consumer, TokenSecret) -> + uri_join([consumer_secret(Consumer), TokenSecret]). -consumer_secret(_Consumer={_, Secret, _}) -> - Secret. +plaintext_verify(Signature, Consumer, TokenSecret) -> + verify_in_constant_time(Signature, plaintext_signature(Consumer, TokenSecret)). -consumer_key(_Consumer={Key, _, _}) -> +hmac_sha1_signature(HttpMethod, URL, Params, Consumer, TokenSecret) -> + BaseString = signature_base_string(HttpMethod, URL, Params), + hmac_sha1_signature(BaseString, Consumer, TokenSecret). + +hmac_sha1_signature(BaseString, Consumer, TokenSecret) -> + Key = uri_join([consumer_secret(Consumer), TokenSecret]), + base64:encode_to_string(crypto:sha_mac(Key, BaseString)). + +hmac_sha1_verify(Signature, HttpMethod, URL, Params, Consumer, TokenSecret) -> + verify_in_constant_time(Signature, hmac_sha1_signature(HttpMethod, URL, Params, Consumer, TokenSecret)). + +hmac_sha1_verify(Signature, BaseString, Consumer, TokenSecret) -> + verify_in_constant_time(Signature, hmac_sha1_signature(BaseString, Consumer, TokenSecret)). + +rsa_sha1_signature(HttpMethod, URL, Params, Consumer) -> + BaseString = signature_base_string(HttpMethod, URL, Params), + rsa_sha1_signature(BaseString, Consumer). + +rsa_sha1_signature(BaseString, Consumer) -> + Key = read_private_key(consumer_secret(Consumer)), + base64:encode_to_string(public_key:sign(list_to_binary(BaseString), sha, Key)). + +rsa_sha1_verify(Signature, HttpMethod, URL, Params, Consumer) -> + BaseString = signature_base_string(HttpMethod, URL, Params), + rsa_sha1_verify(Signature, BaseString, Consumer). + +rsa_sha1_verify(Signature, BaseString, Consumer) -> + Key = read_cert_key(consumer_secret(Consumer)), + public_key:verify(to_binary(BaseString), sha, base64:decode(Signature), Key). + +verify_in_constant_time(<>, <>) -> + verify_in_constant_time(binary_to_list(X), binary_to_list(Y)); +verify_in_constant_time(X, Y) when is_list(X) and is_list(Y) -> + case length(X) == length(Y) of + true -> + verify_in_constant_time(X, Y, 0); + false -> + false + end. + +verify_in_constant_time([X | RestX], [Y | RestY], Result) -> + verify_in_constant_time(RestX, RestY, (X bxor Y) bor Result); +verify_in_constant_time([], [], Result) -> + Result == 0. + +signature_base_string(HttpMethod, URL, Params) -> + uri_join([HttpMethod, uri_normalize(URL), params_encode(Params)]). + +params_encode(Params) -> + % cf. http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 + Encoded = [{uri_encode(K), uri_encode(V)} || {K, V} <- Params], + Sorted = lists:sort(Encoded), + Concatenated = [lists:concat([K, "=", V]) || {K, V} <- Sorted], + string:join(Concatenated, "&"). + +params_decode(_Response={{_, _, _}, _, Body}) -> + uri_params_decode(Body). + +http_request(Method, Request, Options) -> + httpc:request(Method, Request, [{autoredirect, false}], Options). + +unix_timestamp() -> + unix_timestamp(calendar:universal_time()). + +unix_timestamp(DateTime) -> + unix_seconds(DateTime) - unix_epoch(). + +unix_epoch() -> + unix_seconds({{1970,1,1},{00,00,00}}). + +unix_seconds(DateTime) -> + calendar:datetime_to_gregorian_seconds(DateTime). + +read_cert_key(Path) when is_list(Path) -> + {ok, Contents} = file:read_file(Path), + [{'Certificate', DerCert, not_encrypted}] = public_key:pem_decode(Contents), + read_cert_key(public_key:pkix_decode_cert(DerCert, otp)); +read_cert_key(#'OTPCertificate'{tbsCertificate=Cert}) -> + read_cert_key(Cert); +read_cert_key(#'OTPTBSCertificate'{subjectPublicKeyInfo=Info}) -> + read_cert_key(Info); +read_cert_key(#'OTPSubjectPublicKeyInfo'{subjectPublicKey=Key}) -> Key. + +read_private_key(Path) -> + {ok, Contents} = file:read_file(Path), + [Info] = public_key:pem_decode(Contents), + public_key:pem_entry_decode(Info). + +to_binary(Term) when is_list(Term) -> + list_to_binary(Term); +to_binary(Term) when is_binary(Term) -> + Term. + +header_params_encode(Params) -> + intercalate(", ", [lists:concat([uri_encode(K), "=\"", uri_encode(V), "\""]) || {K, V} <- Params]). + +header_params_decode(String) -> + [header_param_decode(Param) || Param <- re:split(String, ",\\s*", [{return, list}]), Param =/= ""]. + +header_param_decode(Param) -> + [Key, QuotedValue] = string:tokens(Param, "="), + Value = string:substr(QuotedValue, 2, length(QuotedValue) - 2), + {uri_decode(Key), uri_decode(Value)}. + +uri_normalize(URI) -> + case http_uri:parse(URI) of + {ok, {Scheme, UserInfo, Host, Port, Path, _Query}} -> % R15B + uri_normalize(Scheme, UserInfo, string:to_lower(Host), Port, [Path]); + {Scheme, UserInfo, Host, Port, Path, _Query} -> + uri_normalize(Scheme, UserInfo, string:to_lower(Host), Port, [Path]); + Else -> + Else + end. + +uri_normalize(http, UserInfo, Host, 80, Acc) -> + uri_normalize(http, UserInfo, [Host|Acc]); +uri_normalize(https, UserInfo, Host, 443, Acc) -> + uri_normalize(https, UserInfo, [Host|Acc]); +uri_normalize(Scheme, UserInfo, Host, Port, Acc) -> + uri_normalize(Scheme, UserInfo, [Host, ":", Port|Acc]). + +uri_normalize(Scheme, [], Acc) -> + lists:concat([Scheme, "://" | Acc]); +uri_normalize(Scheme, UserInfo, Acc) -> + lists:concat([Scheme, "://", UserInfo, "@" | Acc]). + +uri_params_encode(Params) -> + intercalate("&", [uri_join([K, V], "=") || {K, V} <- Params]). + +uri_params_decode(String) -> + [uri_param_decode(Substring) || Substring <- string:tokens(String, "&")]. + +uri_param_decode(String) -> + [Key, Value] = string:tokens(String, "="), + {uri_decode(Key), uri_decode(Value)}. + +uri_join(Values) -> + uri_join(Values, "&"). + +uri_join(Values, Separator) -> + string:join([uri_encode(Value) || Value <- Values], Separator). + +intercalate(Sep, Xs) -> + lists:concat(intersperse(Sep, Xs)). + +intersperse(_, []) -> + []; +intersperse(_, [X]) -> + [X]; +intersperse(Sep, [X | Xs]) -> + [X, Sep | intersperse(Sep, Xs)]. + +uri_encode(Term) when is_integer(Term) -> + integer_to_list(Term); +uri_encode(Term) when is_atom(Term) -> + uri_encode(atom_to_list(Term)); +uri_encode(Term) when is_list(Term) -> + uri_encode(lists:reverse(Term, []), []). + +-define(is_alphanum(C), C >= $A, C =< $Z; C >= $a, C =< $z; C >= $0, C =< $9). + +uri_encode([X | T], Acc) when ?is_alphanum(X); X =:= $-; X =:= $_; X =:= $.; X =:= $~ -> + uri_encode(T, [X | Acc]); +uri_encode([X | T], Acc) -> + NewAcc = [$%, dec2hex(X bsr 4), dec2hex(X band 16#0f) | Acc], + uri_encode(T, NewAcc); +uri_encode([], Acc) -> + Acc. + +uri_decode(Str) when is_list(Str) -> + uri_decode(Str, []). + +uri_decode([$%, A, B | T], Acc) -> + uri_decode(T, [(hex2dec(A) bsl 4) + hex2dec(B) | Acc]); +uri_decode([X | T], Acc) -> + uri_decode(T, [X | Acc]); +uri_decode([], Acc) -> + lists:reverse(Acc, []). + +-compile({inline, [{dec2hex, 1}, {hex2dec, 1}]}). + +dec2hex(N) when N >= 10 andalso N =< 15 -> + N + $A - 10; +dec2hex(N) when N >= 0 andalso N =< 9 -> + N + $0. + +hex2dec(C) when C >= $A andalso C =< $F -> + C - $A + 10; +hex2dec(C) when C >= $0 andalso C =< $9 -> + C - $0. http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_hmac_sha1.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_hmac_sha1.erl b/src/erlang-oauth/oauth_hmac_sha1.erl deleted file mode 100644 index 35549cf..0000000 --- a/src/erlang-oauth/oauth_hmac_sha1.erl +++ /dev/null @@ -1,11 +0,0 @@ --module(oauth_hmac_sha1). - --export([signature/3, verify/4]). - - -signature(BaseString, CS, TS) -> - Key = oauth_uri:calate("&", [CS, TS]), - base64:encode_to_string(crypto:sha_mac(Key, BaseString)). - -verify(Signature, BaseString, CS, TS) -> - couch_util:verify(Signature, signature(BaseString, CS, TS)). http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_http.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_http.erl b/src/erlang-oauth/oauth_http.erl deleted file mode 100644 index 92c806c..0000000 --- a/src/erlang-oauth/oauth_http.erl +++ /dev/null @@ -1,22 +0,0 @@ --module(oauth_http). - --export([get/1, post/2, response_params/1, response_body/1, response_code/1]). - - -get(URL) -> - request(get, {URL, []}). - -post(URL, Data) -> - request(post, {URL, [], "application/x-www-form-urlencoded", Data}). - -request(Method, Request) -> - httpc:request(Method, Request, [{autoredirect, false}], []). - -response_params(Response) -> - oauth_uri:params_from_string(response_body(Response)). - -response_body({{_, _, _}, _, Body}) -> - Body. - -response_code({{_, Code, _}, _, _}) -> - Code. http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_plaintext.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_plaintext.erl b/src/erlang-oauth/oauth_plaintext.erl deleted file mode 100644 index 9544a0a..0000000 --- a/src/erlang-oauth/oauth_plaintext.erl +++ /dev/null @@ -1,10 +0,0 @@ --module(oauth_plaintext). - --export([signature/2, verify/3]). - - -signature(CS, TS) -> - oauth_uri:calate("&", [CS, TS]). - -verify(Signature, CS, TS) -> - couch_util:verify(Signature, signature(CS, TS)). http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_rsa_sha1.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_rsa_sha1.erl b/src/erlang-oauth/oauth_rsa_sha1.erl deleted file mode 100644 index 6f4828e..0000000 --- a/src/erlang-oauth/oauth_rsa_sha1.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(oauth_rsa_sha1). - --export([signature/2, verify/3]). - --include_lib("public_key/include/public_key.hrl"). - - -signature(BaseString, PrivateKeyPath) -> - {ok, [Info]} = public_key:pem_to_der(PrivateKeyPath), - {ok, PrivateKey} = public_key:decode_private_key(Info), - base64:encode_to_string(public_key:sign(list_to_binary(BaseString), PrivateKey)). - -verify(Signature, BaseString, PublicKey) -> - public_key:verify_signature(to_binary(BaseString), sha, base64:decode(Signature), public_key(PublicKey)). - -to_binary(Term) when is_list(Term) -> - list_to_binary(Term); -to_binary(Term) when is_binary(Term) -> - Term. - -public_key(Path) when is_list(Path) -> - {ok, [{cert, DerCert, not_encrypted}]} = public_key:pem_to_der(Path), - {ok, Cert} = public_key:pkix_decode_cert(DerCert, otp), - public_key(Cert); -public_key(#'OTPCertificate'{tbsCertificate=Cert}) -> - public_key(Cert); -public_key(#'OTPTBSCertificate'{subjectPublicKeyInfo=Info}) -> - public_key(Info); -public_key(#'OTPSubjectPublicKeyInfo'{subjectPublicKey=Key}) -> - Key. http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_unix.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_unix.erl b/src/erlang-oauth/oauth_unix.erl deleted file mode 100644 index 73ca314..0000000 --- a/src/erlang-oauth/oauth_unix.erl +++ /dev/null @@ -1,16 +0,0 @@ --module(oauth_unix). - --export([timestamp/0]). - - -timestamp() -> - timestamp(calendar:universal_time()). - -timestamp(DateTime) -> - seconds(DateTime) - epoch(). - -epoch() -> - seconds({{1970,1,1},{00,00,00}}). - -seconds(DateTime) -> - calendar:datetime_to_gregorian_seconds(DateTime). http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/src/erlang-oauth/oauth_uri.erl ---------------------------------------------------------------------- diff --git a/src/erlang-oauth/oauth_uri.erl b/src/erlang-oauth/oauth_uri.erl deleted file mode 100644 index aebf093..0000000 --- a/src/erlang-oauth/oauth_uri.erl +++ /dev/null @@ -1,100 +0,0 @@ --module(oauth_uri). - --export([normalize/1, calate/2, encode/1]). --export([params_from_string/1, params_to_string/1, - params_from_header_string/1, params_to_header_string/1]). - --import(lists, [concat/1]). - - -normalize(URI) -> - case http_uri:parse(URI) of - {ok, {Scheme, UserInfo, Host, Port, Path, _Query}} -> % R15B - normalize(Scheme, UserInfo, string:to_lower(Host), Port, [Path]); - {Scheme, UserInfo, Host, Port, Path, _Query} -> - normalize(Scheme, UserInfo, string:to_lower(Host), Port, [Path]); - Else -> - Else - end. - -normalize(http, UserInfo, Host, 80, Acc) -> - normalize(http, UserInfo, [Host|Acc]); -normalize(https, UserInfo, Host, 443, Acc) -> - normalize(https, UserInfo, [Host|Acc]); -normalize(Scheme, UserInfo, Host, Port, Acc) -> - normalize(Scheme, UserInfo, [Host, ":", Port|Acc]). - -normalize(Scheme, [], Acc) -> - concat([Scheme, "://"|Acc]); -normalize(Scheme, UserInfo, Acc) -> - concat([Scheme, "://", UserInfo, "@"|Acc]). - -params_to_header_string(Params) -> - intercalate(", ", [concat([encode(K), "=\"", encode(V), "\""]) || {K, V} <- Params]). - -params_from_header_string(String) -> - [param_from_header_string(Param) || Param <- re:split(String, ",\\s*", [{return, list}]), Param =/= ""]. - -param_from_header_string(Param) -> - [Key, QuotedValue] = string:tokens(Param, "="), - Value = string:substr(QuotedValue, 2, length(QuotedValue) - 2), - {decode(Key), decode(Value)}. - -params_from_string(Params) -> - [param_from_string(Param) || Param <- string:tokens(Params, "&")]. - -param_from_string(Param) -> - list_to_tuple([decode(Value) || Value <- string:tokens(Param, "=")]). - -params_to_string(Params) -> - intercalate("&", [calate("=", [K, V]) || {K, V} <- Params]). - -calate(Sep, Xs) -> - intercalate(Sep, [encode(X) || X <- Xs]). - -intercalate(Sep, Xs) -> - concat(intersperse(Sep, Xs)). - -intersperse(_, []) -> []; -intersperse(_, [X]) -> [X]; -intersperse(Sep, [X|Xs]) -> - [X, Sep|intersperse(Sep, Xs)]. - --define(is_alphanum(C), C >= $A, C =< $Z; C >= $a, C =< $z; C >= $0, C =< $9). - -encode(Term) when is_integer(Term) -> - integer_to_list(Term); -encode(Term) when is_atom(Term) -> - encode(atom_to_list(Term)); -encode(Term) when is_list(Term) -> - encode(lists:reverse(Term, []), []). - -encode([X | T], Acc) when ?is_alphanum(X); X =:= $-; X =:= $_; X =:= $.; X =:= $~ -> - encode(T, [X | Acc]); -encode([X | T], Acc) -> - NewAcc = [$%, dec2hex(X bsr 4), dec2hex(X band 16#0f) | Acc], - encode(T, NewAcc); -encode([], Acc) -> - Acc. - -decode(Str) when is_list(Str) -> - decode(Str, []). - -decode([$%, A, B | T], Acc) -> - decode(T, [(hex2dec(A) bsl 4) + hex2dec(B) | Acc]); -decode([X | T], Acc) -> - decode(T, [X | Acc]); -decode([], Acc) -> - lists:reverse(Acc, []). - --compile({inline, [{dec2hex, 1}, {hex2dec, 1}]}). - -dec2hex(N) when N >= 10 andalso N =< 15 -> - N + $A - 10; -dec2hex(N) when N >= 0 andalso N =< 9 -> - N + $0. - -hex2dec(C) when C >= $A andalso C =< $F -> - C - $A + 10; -hex2dec(C) when C >= $0 andalso C =< $9 -> - C - $0. http://git-wip-us.apache.org/repos/asf/couchdb/blob/d74e93c9/test/etap/160-vhosts.t ---------------------------------------------------------------------- diff --git a/test/etap/160-vhosts.t b/test/etap/160-vhosts.t index 94882fe..46fdd73 100755 --- a/test/etap/160-vhosts.t +++ b/test/etap/160-vhosts.t @@ -335,7 +335,7 @@ test_vhost_request_with_oauth(Db) -> Url = "http://oauth-example.com/", Consumer = {"consec1", "foo", hmac_sha1}, - SignedParams = oauth:signed_params( + SignedParams = oauth:sign( "GET", Url, [], Consumer, "otoksec1", "foobar"), OAuthUrl = oauth:uri(server(), SignedParams), @@ -350,7 +350,7 @@ test_vhost_request_with_oauth(Db) -> end, Consumer2 = {"consec1", "bad_secret", hmac_sha1}, - SignedParams2 = oauth:signed_params( + SignedParams2 = oauth:sign( "GET", Url, [], Consumer2, "otoksec1", "foobar"), OAuthUrl2 = oauth:uri(server(), SignedParams2),