You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/05/20 07:22:20 UTC

[apisix] 03/07: fix: the client verify flag might not be set (#6906)

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

spacewander pushed a commit to branch release/2.10
in repository https://gitbox.apache.org/repos/asf/apisix.git

commit c2eff65dca402ec2e6502be3daef1c9eac52f9af
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Fri Apr 22 19:35:20 2022 +0800

    fix: the client verify flag might not be set (#6906)
    
    A more suitable way is to reject the client TLS handshake directly, just
    like what Go has done.
    
    Fix #6896
    Signed-off-by: spacewander <sp...@gmail.com>
---
 apisix/init.lua                     | 25 ++++++++++++++++---------
 apisix/ssl/router/radixtree_sni.lua |  8 +++++---
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/apisix/init.lua b/apisix/init.lua
index 06daccab2..eb6ebf0a6 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -26,6 +26,7 @@ local get_var         = require("resty.ngxvar").fetch
 local router          = require("apisix.router")
 local apisix_upstream = require("apisix.upstream")
 local set_upstream    = apisix_upstream.set_by_route
+local apisix_ssl      = require("apisix.ssl")
 local upstream_util   = require("apisix.utils.upstream")
 local ctxdump         = require("resty.ctxdump")
 local ipmatcher       = require("resty.ipmatcher")
@@ -320,7 +321,13 @@ local function verify_tls_client(ctx)
         return true
     end
 
-    if ctx and ctx.ssl_client_verified then
+    local matched = router.router_ssl.match_and_set(ctx, true)
+    if not matched then
+        return true
+    end
+
+    local matched_ssl = ctx.matched_ssl
+    if matched_ssl.value.client and apisix_ssl.support_client_verification() then
         local res = ngx_var.ssl_client_verify
         if res ~= "SUCCESS" then
             if res == "NONE" then
@@ -357,14 +364,14 @@ end
 function _M.http_access_phase()
     local ngx_ctx = ngx.ctx
 
-    if not verify_tls_client(ngx_ctx.api_ctx) then
-        return core.response.exit(400)
-    end
-
     -- always fetch table from the table pool, we don't need a reused api_ctx
     local api_ctx = core.tablepool.fetch("api_ctx", 0, 32)
     ngx_ctx.api_ctx = api_ctx
 
+    if not verify_tls_client(api_ctx) then
+        return core.response.exit(400)
+    end
+
     core.ctx.set_vars_meta(api_ctx)
 
     debug.dynamic_debug(api_ctx)
@@ -881,15 +888,15 @@ function _M.stream_preread_phase()
     local ngx_ctx = ngx.ctx
     local api_ctx = ngx_ctx.api_ctx
 
-    if not verify_tls_client(ngx_ctx.api_ctx) then
-        return ngx_exit(1)
-    end
-
     if not api_ctx then
         api_ctx = core.tablepool.fetch("api_ctx", 0, 32)
         ngx_ctx.api_ctx = api_ctx
     end
 
+    if not verify_tls_client(api_ctx) then
+        return ngx_exit(1)
+    end
+
     core.ctx.set_vars_meta(api_ctx)
 
     local ok, err = router.router_stream.match(api_ctx)
diff --git a/apisix/ssl/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua
index 433ed2de0..176559325 100644
--- a/apisix/ssl/router/radixtree_sni.lua
+++ b/apisix/ssl/router/radixtree_sni.lua
@@ -117,7 +117,7 @@ local function set_pem_ssl_key(sni, cert, pkey)
 end
 
 
-function _M.match_and_set(api_ctx)
+function _M.match_and_set(api_ctx, match_only)
     local err
     if not radixtree_router or
        radixtree_router_ver ~= ssl_certificates.conf_version then
@@ -175,6 +175,10 @@ function _M.match_and_set(api_ctx)
     local matched_ssl = api_ctx.matched_ssl
     core.log.info("debug - matched: ", core.json.delay_encode(matched_ssl, true))
 
+    if match_only then
+        return true
+    end
+
     ngx_ssl.clear_certs()
 
     ok, err = set_pem_ssl_key(sni, matched_ssl.value.cert,
@@ -209,8 +213,6 @@ function _M.match_and_set(api_ctx)
             if not ok then
                 return false, err
             end
-
-            api_ctx.ssl_client_verified = true
         end
     end