You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2020/09/03 16:42:18 UTC

[couchdb] branch improve_jwtf_keystore_error_handling created (now 72a0488)

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a change to branch improve_jwtf_keystore_error_handling
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


      at 72a0488  return a clean error if pem_decode fails

This branch includes the following new commits:

     new 26be86b  buffer response before sending it
     new 72a0488  return a clean error if pem_decode fails

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb] 02/02: return a clean error if pem_decode fails

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch improve_jwtf_keystore_error_handling
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 72a0488dd655493025b50f586e2106a8ab854f95
Author: Robert Newson <rn...@apache.org>
AuthorDate: Thu Sep 3 17:41:01 2020 +0100

    return a clean error if pem_decode fails
---
 src/jwtf/src/jwtf_keystore.erl        | 17 +++++++++++------
 src/jwtf/test/jwtf_keystore_tests.erl | 11 +++++++++--
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/jwtf/src/jwtf_keystore.erl b/src/jwtf/src/jwtf_keystore.erl
index c2d80b9..38551d9 100644
--- a/src/jwtf/src/jwtf_keystore.erl
+++ b/src/jwtf/src/jwtf_keystore.erl
@@ -141,12 +141,17 @@ get_from_config(Kty, KID) ->
 
 pem_decode(PEM) ->
     BinPEM = re:replace(PEM, "\\\\n", "\n", [global, {return, binary}]),
-    case public_key:pem_decode(BinPEM) of
-        [PEMEntry] ->
-            public_key:pem_entry_decode(PEMEntry);
-        [] ->
-            throw({bad_request, <<"Not a valid key">>})
-    end.
+    try
+        case public_key:pem_decode(BinPEM) of
+            [PEMEntry] ->
+                public_key:pem_entry_decode(PEMEntry);
+            [] ->
+                throw({bad_request, <<"Not a valid key">>})
+        end
+   catch
+       error:Reason ->
+           {error, Reason}
+   end.
 
 kty(<<"HS", _/binary>>) ->
     "hmac";
diff --git a/src/jwtf/test/jwtf_keystore_tests.erl b/src/jwtf/test/jwtf_keystore_tests.erl
index 9ec9436..26dbea3 100644
--- a/src/jwtf/test/jwtf_keystore_tests.erl
+++ b/src/jwtf/test/jwtf_keystore_tests.erl
@@ -17,6 +17,8 @@
 
 -define(HMAC_SECRET, "aGVsbG8=").
 -define(RSA_SECRET, "-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAztanwQtIx0sms+x7m1SF\\nh7EHJHkM2biTJ41jR89FsDE2gd3MChpaqxemS5GpNvfFKRvuHa4PUZ3JtRCBG1KM\\n/7EWIVTy1JQDr2mb8couGlQNqz4uXN2vkNQ0XszgjU4Wn6ZpvYxmqPFbmkRe8QSn\\nAy2Wf8jQgjsbez8eaaX0G9S1hgFZUN3KFu7SVmUDQNvWpQdaJPP+ms5Z0CqF7JLa\\nvJmSdsU49nlYw9VH/XmwlUBMye6HgR4ZGCLQS85frqF0xLWvi7CsMdchcIjHudXH\\nQK1AumD/VVZVdi8Q5Qew7F6VXeXqnhbw9n6Px25cCuNuh6u5+E6GUzXRrMpqo9vO\\nqQIDAQAB\\n-----END PUBLIC KEY-----\\n").
+-define(BAD_RSA_SECRET,"-----BEGIN PUBLIC KEY-----\\nMIIDAzCCAeugAwIBAgIJAL5YnwkF5jT6MA0GCSqGSIb3DQEBBQUAMBgxFjAUBgNV\\nBAMMDWZvby5hdXRoMC5jb20wHhcNMTQwMzE4MjAwNzUwWhcNMjcxMTI1MjAwNzUw\\nWjAYMRYwFAYDVQQDDA1mb28uYXV0aDAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC\\nAQ8AMIIBCgKCAQEAtP6w43ppU0nkqGNHASojFJl60+k3isNVzYTO06f2vm/5tc3l\\nRhEA6ykyIuO8tHY3Ziqowc4h8XGaeDKqHw/BSS/b54F2rUVb/wACWyJICkM3bGtC\\ntWmM7kU8XZRCqXV04qIgQte+9GFSOax/TFyotS+FGFyFPUY+b57H7/6wNQ8ywGLi\\nWCbrWEx4wOJbGhnVNV+STmZXJgToLgz0R2kws [...]
+
 -define(EC_SECRET, "-----BEGIN PUBLIC KEY-----\\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEDsr0lz/Dg3luarb+Kua0Wcj9WrfR23os\\nwHzakglb8GhWRDn+oZT0Bt/26sX8uB4/ij9PEOLHPo+IHBtX4ELFFVr5GTzlqcJe\\nyctaTDd1OOAPXYuc67EWtGZ3pDAzztRs\\n-----END PUBLIC KEY-----\\n").
 
 setup() ->
@@ -31,7 +33,10 @@ setup() ->
 
     config:set("jwt_keys", "hmac:ec", ?EC_SECRET),
     config:set("jwt_keys", "rsa:ec", ?EC_SECRET),
-    config:set("jwt_keys", "ec:ec", ?EC_SECRET).
+    config:set("jwt_keys", "ec:ec", ?EC_SECRET),
+
+    config:set("jwt_keys", "rsa:badrsa", ?BAD_RSA_SECRET).
+
 
 teardown(_) ->
     test_util:stop_applications([config, jwtf]).
@@ -52,6 +57,8 @@ jwtf_keystore_test_() ->
 
       ?_assertThrow({bad_request, _},  jwtf_keystore:get(<<"HS256">>, <<"ec">>)),
       ?_assertThrow({bad_request, _},  jwtf_keystore:get(<<"RS256">>, <<"ec">>)),
-      ?_assertMatch({#'ECPoint'{}, _}, jwtf_keystore:get(<<"ES256">>, <<"ec">>))
+      ?_assertMatch({#'ECPoint'{}, _}, jwtf_keystore:get(<<"ES256">>, <<"ec">>)),
+
+      ?_assertThrow({bad_request, <<"not an RSA public key">>}, jwtf_keystore:get(<<"RS256">>, <<"badrsa">>))
      ]
     }.


[couchdb] 01/02: buffer response before sending it

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch improve_jwtf_keystore_error_handling
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 26be86b93798840e98d8b9b4ca1f3170a3b40f39
Author: Robert Newson <rn...@apache.org>
AuthorDate: Wed Sep 2 13:31:09 2020 +0100

    buffer response before sending it
---
 src/chttpd/src/chttpd.erl | 46 ++++++++++++++++------------------------------
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index adde073..1343531 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -52,7 +52,7 @@
     req,
     code,
     headers,
-    first_chunk,
+    chunks,
     resp=nil
 }).
 
@@ -792,7 +792,7 @@ start_delayed_json_response(Req, Code, Headers, FirstChunk) ->
         req = Req,
         code = Code,
         headers = Headers,
-        first_chunk = FirstChunk}}.
+        chunks = [FirstChunk]}}.
 
 start_delayed_chunked_response(Req, Code, Headers) ->
     start_delayed_chunked_response(Req, Code, Headers, "").
@@ -803,13 +803,11 @@ start_delayed_chunked_response(Req, Code, Headers, FirstChunk) ->
         req = Req,
         code = Code,
         headers = Headers,
-        first_chunk = FirstChunk}}.
+        chunks = [FirstChunk]}}.
 
 send_delayed_chunk(#delayed_resp{}=DelayedResp, Chunk) ->
-    {ok, #delayed_resp{resp=Resp}=DelayedResp1} =
-        start_delayed_response(DelayedResp),
-    {ok, Resp} = send_chunk(Resp, Chunk),
-    {ok, DelayedResp1}.
+    #delayed_resp{chunks = Chunks} = DelayedResp,
+    {ok, DelayedResp#delayed_resp{chunks = [Chunk | Chunks]}}.
 
 send_delayed_last_chunk(Req) ->
     send_delayed_chunk(Req, []).
@@ -817,11 +815,7 @@ send_delayed_last_chunk(Req) ->
 send_delayed_error(#delayed_resp{req=Req,resp=nil}=DelayedResp, Reason) ->
     {Code, ErrorStr, ReasonStr} = error_info(Reason),
     {ok, Resp} = send_error(Req, Code, ErrorStr, ReasonStr),
-    {ok, DelayedResp#delayed_resp{resp=Resp}};
-send_delayed_error(#delayed_resp{resp=Resp, req=Req}, Reason) ->
-    update_timeout_stats(Reason, Req),
-    log_error_with_stack_trace(Reason),
-    throw({http_abort, Resp, Reason}).
+    {ok, DelayedResp#delayed_resp{resp=Resp}}.
 
 close_delayed_json_object(Resp, Buffer, Terminator, 0) ->
     % Use a separate chunk to close the streamed array to maintain strict
@@ -832,31 +826,23 @@ close_delayed_json_object(Resp, Buffer, Terminator, _Threshold) ->
     send_delayed_chunk(Resp, [Buffer | Terminator]).
 
 end_delayed_json_response(#delayed_resp{}=DelayedResp) ->
-    {ok, #delayed_resp{resp=Resp}} =
-        start_delayed_response(DelayedResp),
-    end_json_response(Resp).
-
-get_delayed_req(#delayed_resp{req=#httpd{mochi_req=MochiReq}}) ->
-    MochiReq;
-get_delayed_req(Resp) ->
-    Resp:get(request).
-
-start_delayed_response(#delayed_resp{resp=nil}=DelayedResp) ->
     #delayed_resp{
         start_fun=StartFun,
         req=Req,
         code=Code,
         headers=Headers,
-        first_chunk=FirstChunk
+        chunks=Chunks
     }=DelayedResp,
     {ok, Resp} = StartFun(Req, Code, Headers),
-    case FirstChunk of
-        "" -> ok;
-        _ -> {ok, Resp} = send_chunk(Resp, FirstChunk)
-    end,
-    {ok, DelayedResp#delayed_resp{resp=Resp}};
-start_delayed_response(#delayed_resp{}=DelayedResp) ->
-    {ok, DelayedResp}.
+    lists:foreach(fun(Chunk) -> send_chunk(Resp, Chunk) end,
+        lists:reverse(Chunks)),
+    end_json_response(Resp).
+
+get_delayed_req(#delayed_resp{req=#httpd{mochi_req=MochiReq}}) ->
+    MochiReq;
+get_delayed_req(Resp) ->
+    Resp:get(request).
+
 
 error_info({Error, Reason}) when is_list(Reason) ->
     error_info({Error, couch_util:to_binary(Reason)});