From 05e0ed295bd8c1b0825572b8c9583d5ae68d4705 Mon Sep 17 00:00:00 2001 From: Xumin <100666470+StarlightIbuki@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:09:19 +0800 Subject: [PATCH] feat(ssl): add a function to get request ssl pointer (#95) Introduce a new API to get the SSL pointer for the current request. KAG-5388, KAG-5473 --------- Co-authored-by: Qi --- README.md | 16 +++++++++ lualib/resty/kong/tls.lua | 21 +++++++++++- src/ngx_http_lua_kong_ssl.c | 23 +++++++++++++ stream/src/ngx_stream_lua_kong_module.c | 1 - t/001-tls.t | 45 ++++++++++++++++++++++++- valgrind.suppress | 24 +++++++++++++ 6 files changed, 127 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5dc6f2aa..a576fdde 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Table of Contents * [resty.kong.tls.set\_upstream\_ssl\_verify](#restykongtlsset_upstream_ssl_verify) * [resty.kong.tls.set\_upstream\_ssl\_verify\_depth](#restykongtlsset_upstream_ssl_verify_depth) * [resty.kong.tls.get\_ssl\_pointer](#restykongtlsget_ssl_pointer) + * [resty.kong.tls.get\_request\_ssl\_pointer](#restykongtlsget_request_ssl_pointer) * [resty.kong.grpc.set\_authority](#restykonggrpcset_authority) * [resty.kong.tls.disable\_proxy\_ssl](#restykongtlsdisable_proxy_ssl) * [resty.kong.var.patch\_metatable](#restykongvarpatch_metatable) @@ -367,6 +368,21 @@ describing the error will be returned. [Back to TOC](#table-of-contents) +resty.kong.tls.get\_request\_ssl\_pointer +---------------------------------------------------- +**syntax:** *ssl_ptr, err = resty.kong.get\_request\_ssl\_pointer()* + +**context:** *client_hello_by_lua*, *ssl_certificate_by_lua*, *rewrite_by_lua*, access_by_lua*, content_by_lua*, log_by_lua** + +**subsystems:** *http* + +Retrieves the OpenSSL `SSL*` object for the current HTTP request. + +On success, this function returns the pointer of type `SSL`. Otherwise `nil` and a string +describing the error will be returned. + +[Back to TOC](#table-of-contents) + resty.kong.grpc.set\_authority ------------------------------ **syntax:** *ok, err = resty.kong.grpc.set_authority(new_authority)* diff --git a/lualib/resty/kong/tls.lua b/lualib/resty/kong/tls.lua index 23c591ce..648d5342 100644 --- a/lualib/resty/kong/tls.lua +++ b/lualib/resty/kong/tls.lua @@ -40,7 +40,7 @@ local kong_lua_kong_ffi_set_upstream_ssl_trusted_store local kong_lua_kong_ffi_set_upstream_ssl_verify local kong_lua_kong_ffi_set_upstream_ssl_verify_depth local kong_lua_kong_ffi_get_socket_ssl - +local kong_lua_kong_ffi_get_request_ssl if subsystem == "http" then ffi.cdef([[ typedef struct ssl_st SSL; @@ -59,6 +59,8 @@ if subsystem == "http" then int depth); int ngx_http_lua_kong_ffi_get_socket_ssl(ngx_http_lua_socket_tcp_upstream_t *u, void **ssl_conn); + int ngx_http_lua_kong_ffi_get_request_ssl(ngx_http_request_t *r, + void **ssl_conn); ]]) kong_lua_kong_ffi_get_full_client_certificate_chain = C.ngx_http_lua_kong_ffi_get_full_client_certificate_chain @@ -68,6 +70,8 @@ if subsystem == "http" then kong_lua_kong_ffi_set_upstream_ssl_verify = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify kong_lua_kong_ffi_set_upstream_ssl_verify_depth = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify_depth kong_lua_kong_ffi_get_socket_ssl = C.ngx_http_lua_kong_ffi_get_socket_ssl + kong_lua_kong_ffi_get_request_ssl = C.ngx_http_lua_kong_ffi_get_request_ssl + elseif subsystem == 'stream' then ffi.cdef([[ @@ -97,6 +101,9 @@ elseif subsystem == 'stream' then kong_lua_kong_ffi_set_upstream_ssl_verify = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_verify kong_lua_kong_ffi_set_upstream_ssl_verify_depth = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_verify_depth kong_lua_kong_ffi_get_socket_ssl = C.ngx_stream_lua_kong_get_socket_ssl + kong_lua_kong_ffi_get_request_ssl = function() + error("API not available for the current subsystem") + end else error("unknown subsystem: " .. subsystem) end @@ -151,6 +158,18 @@ function _M.get_ssl_pointer(sock) end +function _M.get_request_ssl_pointer() + local r = get_request() + + local ret = kong_lua_kong_ffi_get_request_ssl(r, void_pp) + if ret ~= NGX_OK then + return nil, "no ssl object" + end + + return ffi_cast(ssl_type, void_pp[0]) +end + + do local ALLOWED_PHASES = { ['rewrite'] = true, diff --git a/src/ngx_http_lua_kong_ssl.c b/src/ngx_http_lua_kong_ssl.c index b0d3e8cf..7e56501b 100644 --- a/src/ngx_http_lua_kong_ssl.c +++ b/src/ngx_http_lua_kong_ssl.c @@ -70,6 +70,29 @@ ngx_http_lua_kong_ffi_get_socket_ssl(ngx_http_lua_socket_tcp_upstream_t *u, void } +int +ngx_http_lua_kong_ffi_get_request_ssl(ngx_http_request_t *r, void **ssl_conn) +{ +#if (NGX_SSL) + if (ssl_conn == NULL) { + return NGX_ABORT; + } + + ngx_connection_t *c = r->connection; + + if (c && (c->ssl) && (c->ssl->connection)) { + *ssl_conn = c->ssl->connection; + return NGX_OK; + } + + return NGX_ERROR; + +#else + return NGX_ABORT; +#endif +} + + #if (NGX_HTTP_SSL) /* diff --git a/stream/src/ngx_stream_lua_kong_module.c b/stream/src/ngx_stream_lua_kong_module.c index 41b8b7f0..10f614a9 100644 --- a/stream/src/ngx_stream_lua_kong_module.c +++ b/stream/src/ngx_stream_lua_kong_module.c @@ -322,4 +322,3 @@ void **ssl_conn) return NGX_ABORT; #endif } - diff --git a/t/001-tls.t b/t/001-tls.t index ada5e479..2cdcfa81 100644 --- a/t/001-tls.t +++ b/t/001-tls.t @@ -5,7 +5,7 @@ use Cwd qw(cwd); repeat_each(2); -plan tests => repeat_each() * (blocks() * 7 - 4); +plan tests => repeat_each() * (blocks() * 7 - 7); my $pwd = cwd(); @@ -495,3 +495,46 @@ ok --- no_error_log [error] [emerg] + + + + +=== TEST 8: ssl.get_request_ssl_pointer works well +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;lualib/?.lua;;"; + lua_ssl_protocols SSLV3 TLSv1 TLSv1.1 TLSv1.2; + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name example.com; + ssl_certificate ../../cert/example.com.crt; + ssl_certificate_key ../../cert/example.com.key; + ssl_session_cache off; + ssl_session_tickets on; + server_tokens off; + + location / { + content_by_lua_block { + local ssl = require "resty.kong.tls" + if ssl.get_request_ssl_pointer() == nil then + ngx.say("cannot get socket") + else + ngx.say("ok") + end + } + } + } +--- config + server_tokens off; + location /t { + proxy_pass https://unix:$TEST_NGINX_HTML_DIR/nginx.sock; + proxy_http_version 1.1; + proxy_set_header Connection ""; + } + +--- request +GET /t +--- response_body +ok +--- no_error_log +[error] +[emerg] diff --git a/valgrind.suppress b/valgrind.suppress index dafb33dc..6bdeac8b 100644 --- a/valgrind.suppress +++ b/valgrind.suppress @@ -295,3 +295,27 @@ fun:ngx_single_process_cycle fun:main } +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:CRYPTO_malloc + fun:ssl_session_dup_intern + fun:ssl_session_dup + fun:tls_process_new_session_ticket + fun:read_state_machine + fun:state_machine + fun:ssl3_read_bytes + fun:ssl3_read_internal + fun:ssl3_read_internal + fun:ssl3_read + fun:SSL_read + fun:ngx_ssl_recv + fun:ngx_http_upstream_process_header + fun:ngx_http_upstream_handler + fun:ngx_epoll_process_events + fun:ngx_process_events_and_timers + fun:ngx_single_process_cycle + fun:main +}