diff --git a/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-core-0.1.17_03-cosocket-mtls.patch b/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-core-0.1.17_03-cosocket-mtls.patch new file mode 100644 index 00000000..78ce9d23 --- /dev/null +++ b/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-core-0.1.17_03-cosocket-mtls.patch @@ -0,0 +1,446 @@ +From ddf9dac29e0dd8376e51b369710e42c948e9d959 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:41:56 -0700 +Subject: =?UTF-8?q?feature:=20implement=20the=20`tcpsock:tlshandshake`=20a?= + =?UTF-8?q?nd=20`tcpsock:sslhandshake`=0Afunctions=20using=20FFI.?= + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 172 ++++++++++++++++++++++++++++++++++ + 2 files changed, 173 insertions(+) + create mode 100644 lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +new file mode 100644 +index 0000000..fe81de5 +--- /dev/null ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -0,0 +1,172 @@ ++local ffi = require("ffi") ++local base = require("resty.core.base") ++ ++local C = ffi.C ++local ffi_string = ffi.string ++local ffi_gc = ffi.gc ++local FFI_ERROR = base.FFI_ERROR ++local FFI_DONE = base.FFI_DONE ++local FFI_OK = base.FFI_OK ++local FFI_AGAIN = base.FFI_AGAIN ++local get_request = base.get_request ++local error = error ++local assert = assert ++local getmetatable = getmetatable ++local type = type ++local select = select ++local co_yield = coroutine._yield ++local table_new = require("table.new") ++local table_clear = require("table.clear") ++ ++if not pcall(ffi.typeof, "ngx_ssl_session_t") then ++ ffi.cdef[[ ++ typedef struct SSL_SESSION ngx_ssl_session_t; ++ ]] ++end ++ ++ffi.cdef[[ ++typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t; ++ ++int ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, ++ int enable_session_reuse, ngx_str_t *server_name, int verify, ++ int ocsp_status_req, char **errmsg); ++int ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t **sess, ++ char **errmsg, int *openssl_error_code); ++void ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess); ++]] ++ ++ ++local SOCKET_CTX_INDEX = 1 ++ ++ ++local errmsg = base.get_errmsg_ptr() ++local session_ptr = ffi.new("ngx_ssl_session_t *[1]") ++local server_name_str = ffi.new("ngx_str_t[1]") ++local openssl_error_code = ffi.new("int[1]") ++local cached_options = table_new(0, 4) ++ ++ ++local function tlshandshake(self, options) ++ if not options then ++ table_clear(cached_options) ++ options = cached_options ++ ++ elseif type(options) ~= "table" then ++ error("bad options table type") ++ end ++ ++ local r = get_request() ++ ++ if not r then ++ error("no request found") ++ end ++ ++ local reused_session = options.reused_session ++ session_ptr[0] = type(reused_session) == "cdata" and reused_session or nil ++ ++ if options.server_name then ++ server_name_str[0].data = options.server_name ++ server_name_str[0].len = #options.server_name ++ ++ else ++ server_name_str[0].data = nil ++ server_name_str[0].len = 0 ++ end ++ ++ local rc = ++ C.ngx_http_lua_ffi_socket_tcp_tlshandshake(r, self[SOCKET_CTX_INDEX], ++ session_ptr[0], ++ reused_session ~= false, ++ server_name_str, ++ options.verify and 1 or 0, ++ options.ocsp_status_req ++ and 1 or 0, ++ errmsg) ++ ++::again:: ++ ++ if rc == FFI_ERROR then ++ if openssl_error_code[0] ~= 0 then ++ return nil, openssl_error_code[0] .. ": " .. ffi_string(errmsg[0]) ++ end ++ ++ return nil, ffi_string(errmsg[0]) ++ end ++ ++ if rc == FFI_DONE then ++ return options.reused_session ++ end ++ ++ if rc == FFI_OK then ++ if options.reused_session == false then ++ return true ++ end ++ ++ rc = C.ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(r, ++ self[SOCKET_CTX_INDEX], session_ptr, errmsg, openssl_error_code) ++ ++ assert(rc == FFI_OK) ++ ++ if session_ptr[0] == nil then ++ return session_ptr[0] ++ end ++ ++ return ffi_gc(session_ptr[0], C.ngx_http_lua_ffi_tls_free_session) ++ end ++ ++ assert(rc == FFI_AGAIN) ++ ++ co_yield() ++ ++ rc = C.ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(r, ++ self[SOCKET_CTX_INDEX], session_ptr, errmsg, openssl_error_code) ++ ++ assert(rc == FFI_OK or rc == FFI_ERROR) ++ ++ goto again ++end ++ ++ ++local function sslhandshake(self, reused_session, server_name, ssl_verify, ++ send_status_req, ...) ++ ++ local n = select("#", ...) ++ if not self or n > 1 then ++ error("ngx.socket sslhandshake: expecting 1 ~ 5 " ++ .. "arguments (including the object), but seen " .. n) ++ end ++ ++ cached_options.reused_session = reused_session ++ cached_options.server_name = server_name ++ cached_options.verify = ssl_verify ++ cached_options.ocsp_status_req = send_status_req ++ ++ local res, err = tlshandshake(self, cached_options) ++ table_clear(cached_options) ++ ++ return res, err ++end ++ ++ ++do ++ local old_socket_tcp = ngx.socket.tcp ++ ++ function ngx.socket.tcp() ++ local sock = old_socket_tcp() ++ local mt = getmetatable(sock) ++ ++ mt.tlshandshake = tlshandshake ++ mt.sslhandshake = sslhandshake ++ ++ ngx.socket.tcp = old_socket_tcp ++ ++ return sock ++ end ++end ++ ++ ++return { ++ version = base.version ++} +-- +2.20.1 + + +From 1b73826f746a9dd04f60c560d47e778fbec2c2d9 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:55:05 -0700 +Subject: change: better error when request context couldn't be found. + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +index fe81de5..e18f40e 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -8,6 +8,7 @@ local FFI_ERROR = base.FFI_ERROR + local FFI_DONE = base.FFI_DONE + local FFI_OK = base.FFI_OK + local FFI_AGAIN = base.FFI_AGAIN ++local FFI_NO_REQ_CTX = base.FFI_NO_REQ_CTX + local get_request = base.get_request + local error = error + local assert = assert +@@ -85,6 +86,10 @@ local function tlshandshake(self, options) + and 1 or 0, + errmsg) + ++ if rc == FFI_NO_REQ_CTX then ++ error("no request ctx found", 2) ++ end ++ + ::again:: + + if rc == FFI_ERROR then +-- +2.20.1 + + +From 0fea325cd7d6ca479afbc8abbc297b4a046bc8c3 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:23:08 -0700 +Subject: cosocket: added client certificate support with TLS handshake. + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +index e18f40e..ed45c8a 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -19,23 +19,18 @@ local co_yield = coroutine._yield + local table_new = require("table.new") + local table_clear = require("table.clear") + +-if not pcall(ffi.typeof, "ngx_ssl_session_t") then +- ffi.cdef[[ +- typedef struct SSL_SESSION ngx_ssl_session_t; +- ]] +-end +- + ffi.cdef[[ + typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t; + + int ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, +- ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, ++ ngx_http_lua_socket_tcp_upstream_t *u, void *sess, + int enable_session_reuse, ngx_str_t *server_name, int verify, +- int ocsp_status_req, char **errmsg); ++ int ocsp_status_req, void *chain, void *pkey, ++ char **errmsg); + int ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, +- ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t **sess, ++ ngx_http_lua_socket_tcp_upstream_t *u, void **sess, + char **errmsg, int *openssl_error_code); +-void ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess); ++void ngx_http_lua_ffi_tls_free_session(void *sess); + ]] + + +@@ -43,7 +38,7 @@ local SOCKET_CTX_INDEX = 1 + + + local errmsg = base.get_errmsg_ptr() +-local session_ptr = ffi.new("ngx_ssl_session_t *[1]") ++local session_ptr = ffi.new("void *[1]") + local server_name_str = ffi.new("ngx_str_t[1]") + local openssl_error_code = ffi.new("int[1]") + local cached_options = table_new(0, 4) +@@ -76,6 +71,21 @@ local function tlshandshake(self, options) + server_name_str[0].len = 0 + end + ++ local client_cert = options.client_cert ++ local client_priv_key = options.client_priv_key ++ if client_cert then ++ if not client_priv_key then ++ error("client certificate supplied without " ++ .. "corresponding private key", 2) ++ end ++ ++ if type(client_cert) ~= "cdata" ++ or type(client_priv_key) ~= "cdata" ++ then ++ error("wrong type of client certificate or private key supplied", 2) ++ end ++ end ++ + local rc = + C.ngx_http_lua_ffi_socket_tcp_tlshandshake(r, self[SOCKET_CTX_INDEX], + session_ptr[0], +@@ -84,6 +94,8 @@ local function tlshandshake(self, options) + options.verify and 1 or 0, + options.ocsp_status_req + and 1 or 0, ++ client_cert, ++ client_priv_key, + errmsg) + + if rc == FFI_NO_REQ_CTX then +-- +2.20.1 + + +From 3ed719e95bc9a0fd1a768c6ead1ca0b8b777905a Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:29:56 -0700 +Subject: style: fixed long line. + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +index ed45c8a..a867c73 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -20,7 +20,8 @@ local table_new = require("table.new") + local table_clear = require("table.clear") + + ffi.cdef[[ +-typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t; ++typedef struct ngx_http_lua_socket_tcp_upstream_s ++ ngx_http_lua_socket_tcp_upstream_t; + + int ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, void *sess, +-- +2.20.1 + + +From 036a7f9b431c7d00fb905533a8f57c7e93f8e0a2 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Tue, 24 Sep 2019 16:10:13 -0700 +Subject: =?UTF-8?q?fix:=20transparently=20propagate=20error=20message=20wh?= + =?UTF-8?q?en=20monkey=20patching=20TCP=0Asocket=20metatable.?= + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +index a867c73..a4f4eee 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -14,6 +14,7 @@ local error = error + local assert = assert + local getmetatable = getmetatable + local type = type ++local pcall = pcall + local select = select + local co_yield = coroutine._yield + local table_new = require("table.new") +@@ -172,7 +173,11 @@ do + local old_socket_tcp = ngx.socket.tcp + + function ngx.socket.tcp() +- local sock = old_socket_tcp() ++ local ok, sock = pcall(old_socket_tcp) ++ if not ok then ++ error(sock, 2) ++ end ++ + local mt = getmetatable(sock) + + mt.tlshandshake = tlshandshake +-- +2.20.1 + + +From 75251e09f9950261ce7e587950907ff2982b2e51 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Mon, 28 Oct 2019 14:13:08 -0700 +Subject: load resty.core.socket_tcp to monkypatch the socket metatable + +--- + lua-resty-core-0.1.17/lib/resty/core.lua | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core.lua b/lua-resty-core-0.1.17/lib/resty/core.lua +index 57c9d17..7e8aca4 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core.lua +@@ -21,6 +21,7 @@ if subsystem == 'http' then + require "resty.core.worker" + require "resty.core.phase" + require "resty.core.ndk" ++ require "resty.core.socket_tcp" + end + + +-- +2.20.1 + + +From 8d4d81b2fbfac93b270ef70f6441f0d1c70d999e Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Thu, 5 Dec 2019 14:28:24 -0800 +Subject: [PATCH] do not change metatable to avoid conflicts with possible + other monkypatches on `ngx.socket.tcp` + +--- + lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +index a4f4eee..4cd2d77 100644 +--- a/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua ++++ b/lua-resty-core-0.1.17/lib/resty/core/socket_tcp.lua +@@ -12,7 +12,6 @@ local FFI_NO_REQ_CTX = base.FFI_NO_REQ_CTX + local get_request = base.get_request + local error = error + local assert = assert +-local getmetatable = getmetatable + local type = type + local pcall = pcall + local select = select +@@ -178,12 +177,8 @@ do + error(sock, 2) + end + +- local mt = getmetatable(sock) +- +- mt.tlshandshake = tlshandshake +- mt.sslhandshake = sslhandshake +- +- ngx.socket.tcp = old_socket_tcp ++ sock.tlshandshake = tlshandshake ++ sock.sslhandshake = sslhandshake + + return sock + end +-- +2.20.1 + diff --git a/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-websocket-0.07_01-client-mtls.patch b/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-websocket-0.07_01-client-mtls.patch new file mode 100644 index 00000000..e2e629ed --- /dev/null +++ b/openresty-build-tools/openresty-patches/patches/1.15.8.2/lua-resty-websocket-0.07_01-client-mtls.patch @@ -0,0 +1,64 @@ +diff --git a/lua-resty-websocket-0.07/lib/resty/websocket/client.lua b/lua-resty-websocket-0.07/lib/resty/websocket/client.lua +index 13d4b99..47dc4c2 100644 +--- a/lua-resty-websocket-0.07/lib/resty/websocket/client.lua ++++ b/lua-resty-websocket-0.07/lib/resty/websocket/client.lua +@@ -98,7 +98,7 @@ function _M.connect(self, uri, opts) + path = "/" + end + +- local ssl_verify, proto_header, origin_header, sock_opts = false ++ local ssl_verify, proto_header, origin_header, sock_opts, tls_opts = false + + if opts then + local protos = opts.protocols +@@ -122,11 +122,37 @@ function _M.connect(self, uri, opts) + sock_opts = { pool = pool } + end + ++ local client_cert = opts.client_cert ++ local client_priv_key = opts.client_priv_key ++ ++ if client_cert then ++ assert(client_priv_key, ++ "client_priv_key must be provided with client_cert") ++ ++ tls_opts = { client_cert = client_cert, ++ client_priv_key = client_priv_key, } ++ end ++ + if opts.ssl_verify then + if not ssl_support then + return nil, "ngx_lua 0.9.11+ required for SSL sockets" + end +- ssl_verify = true ++ ++ tls_opts = tls_opts or {} ++ tls_opts.verify = true ++ end ++ ++ if opts.server_name then ++ if not ssl_support then ++ return nil, "ngx_lua 0.9.11+ required for SSL sockets" ++ end ++ ++ tls_opts = tls_opts or {} ++ tls_opts.server_name = opts.server_name ++ ++ elseif host then ++ tls_opts = tls_opts or {} ++ tls_opts.server_name = host + end + end + +@@ -144,9 +170,9 @@ function _M.connect(self, uri, opts) + if not ssl_support then + return nil, "ngx_lua 0.9.11+ required for SSL sockets" + end +- ok, err = sock:sslhandshake(false, host, ssl_verify) ++ ok, err = sock:tlshandshake(tls_opts) + if not ok then +- return nil, "ssl handshake failed: " .. err ++ return nil, "tls handshake failed: " .. err + end + end + diff --git a/openresty-build-tools/openresty-patches/patches/1.15.8.2/ngx_lua-0.10.15_04-cosocket-mtls.patch b/openresty-build-tools/openresty-patches/patches/1.15.8.2/ngx_lua-0.10.15_04-cosocket-mtls.patch new file mode 100644 index 00000000..85e206d6 --- /dev/null +++ b/openresty-build-tools/openresty-patches/patches/1.15.8.2/ngx_lua-0.10.15_04-cosocket-mtls.patch @@ -0,0 +1,842 @@ +From 7ddc2d64c9c9f8f04d2eb9429d3bb89eec6c39e2 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:39:05 -0700 +Subject: =?UTF-8?q?cosocket:=20add=20function=20`tcpsock:tlshandshake`,=20?= + =?UTF-8?q?retired=20the=20Lua=20C=20API=0Abased=20`tcpsock:sslhandshake`?= + =?UTF-8?q?=20implementation.?= + +--- + ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c | 387 +++++++++++++++------------------- + ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.h | 3 + + 4 files changed, 461 insertions(+), 340 deletions(-) + +diff --git a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +index efd5875f..1e3fc91f 100644 +--- a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +@@ -23,6 +23,9 @@ static int ngx_http_lua_socket_tcp(lua_State *L); + static int ngx_http_lua_socket_tcp_connect(lua_State *L); + #if (NGX_HTTP_SSL) + static int ngx_http_lua_socket_tcp_sslhandshake(lua_State *L); ++static void ngx_http_lua_tls_handshake_handler(ngx_connection_t *c); ++static int ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); + #endif + static int ngx_http_lua_socket_tcp_receive(lua_State *L); + static int ngx_http_lua_socket_tcp_receiveany(lua_State *L); +@@ -152,12 +155,6 @@ static void + ngx_http_lua_socket_empty_resolve_handler(ngx_resolver_ctx_t *ctx); + static int ngx_http_lua_socket_prepare_error_retvals(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L, ngx_uint_t ft_type); +-#if (NGX_HTTP_SSL) +-static int ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, +- ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); +-static void ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c); +-static int ngx_http_lua_ssl_free_session(lua_State *L); +-#endif + static void ngx_http_lua_socket_tcp_close_connection(ngx_connection_t *c); + + +@@ -309,13 +306,6 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) + lua_pushcfunction(L, ngx_http_lua_socket_tcp_connect); + lua_setfield(L, -2, "connect"); + +-#if (NGX_HTTP_SSL) +- +- lua_pushcfunction(L, ngx_http_lua_socket_tcp_sslhandshake); +- lua_setfield(L, -2, "sslhandshake"); +- +-#endif +- + lua_pushcfunction(L, ngx_http_lua_socket_tcp_receive); + lua_setfield(L, -2, "receive"); + +@@ -386,19 +376,6 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) + lua_setfield(L, -2, "__gc"); + lua_rawset(L, LUA_REGISTRYINDEX); + /* }}} */ +- +-#if (NGX_HTTP_SSL) +- +- /* {{{ssl session userdata metatable */ +- lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( +- ssl_session_metatable_key)); +- lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */ +- lua_pushcfunction(L, ngx_http_lua_ssl_free_session); +- lua_setfield(L, -2, "__gc"); +- lua_rawset(L, LUA_REGISTRYINDEX); +- /* }}} */ +- +-#endif + } + + +@@ -1531,64 +1508,69 @@ ngx_http_lua_socket_conn_error_retval_handler(ngx_http_request_t *r, + + #if (NGX_HTTP_SSL) + +-static int +-ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) ++static const char * ++ngx_http_lua_socket_tcp_check_busy(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, unsigned int ops) + { +- int n, top; +- ngx_int_t rc; +- ngx_str_t name = ngx_null_string; +- ngx_connection_t *c; +- ngx_ssl_session_t **psession; +- ngx_http_request_t *r; +- ngx_http_lua_ctx_t *ctx; +- ngx_http_lua_co_ctx_t *coctx; +- +- ngx_http_lua_socket_tcp_upstream_t *u; +- +- /* Lua function arguments: self [,session] [,host] [,verify] +- [,send_status_req] */ ++ if (ops & SOCKET_OP_CONNECT && u->conn_waiting) { ++ return "socket busy connecting"; ++ } + +- n = lua_gettop(L); +- if (n < 1 || n > 5) { +- return luaL_error(L, "ngx.socket sslhandshake: expecting 1 ~ 5 " +- "arguments (including the object), but seen %d", n); ++ if (ops & SOCKET_OP_READ && u->read_waiting) { ++ return "socket busy reading"; + } + +- r = ngx_http_lua_get_req(L); +- if (r == NULL) { +- return luaL_error(L, "no request found"); ++ if (ops & SOCKET_OP_WRITE ++ && (u->write_waiting ++ || (u->raw_downstream ++ && (r->connection->buffered & NGX_HTTP_LOWLEVEL_BUFFERED)))) ++ { ++ return "socket busy writing"; + } + +- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua tcp socket ssl handshake"); ++ return NULL; ++} + +- luaL_checktype(L, 1, LUA_TTABLE); ++int ++ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, ++ int enable_session_reuse, ngx_str_t *server_name, int verify, ++ int ocsp_status_req, const char **errmsg) ++{ ++ ngx_int_t rc; ++ ngx_connection_t *c; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_lua_co_ctx_t *coctx; ++ const char *busy_rc; + +- lua_rawgeti(L, 1, SOCKET_CTX_INDEX); +- u = lua_touserdata(L, -1); ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "lua tcp socket tls handshake"); + + if (u == NULL + || u->peer.connection == NULL + || u->read_closed + || u->write_closed) + { +- lua_pushnil(L); +- lua_pushliteral(L, "closed"); +- return 2; ++ *errmsg = "closed"; ++ return NGX_ERROR; + } + + if (u->request != r) { +- return luaL_error(L, "bad request"); ++ *errmsg = "bad request"; ++ return NGX_ERROR; + } + +- ngx_http_lua_socket_check_busy_connecting(r, u, L); +- ngx_http_lua_socket_check_busy_reading(r, u, L); +- ngx_http_lua_socket_check_busy_writing(r, u, L); ++ busy_rc = ngx_http_lua_socket_tcp_check_busy(r, u, SOCKET_OP_CONNECT ++ | SOCKET_OP_READ ++ | SOCKET_OP_WRITE); ++ if (busy_rc != NULL) { ++ *errmsg = busy_rc; ++ return NGX_ERROR; ++ } + + if (u->raw_downstream || u->body_downstream) { +- lua_pushnil(L); +- lua_pushliteral(L, "not supported for downstream"); +- return 2; ++ *errmsg = "not supported for downstream"; ++ return NGX_ERROR; + } + + c = u->peer.connection; +@@ -1596,122 +1578,96 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) + u->ssl_session_reuse = 1; + + if (c->ssl && c->ssl->handshaked) { +- switch (lua_type(L, 2)) { +- case LUA_TUSERDATA: +- lua_pushvalue(L, 2); +- break; ++ if (sess != NULL) { ++ return NGX_DONE; ++ } + +- case LUA_TBOOLEAN: +- if (!lua_toboolean(L, 2)) { +- /* avoid generating the ssl session */ +- lua_pushboolean(L, 1); +- break; +- } +- /* fall through */ ++ u->ssl_session_reuse = enable_session_reuse; + +- default: +- ngx_http_lua_ssl_handshake_retval_handler(r, u, L); +- break; +- } ++ (void) ngx_http_lua_tls_handshake_retval_handler(r, u, NULL); + +- return 1; ++ return NGX_OK; + } + + if (ngx_ssl_create_connection(u->conf->ssl, c, + NGX_SSL_BUFFER|NGX_SSL_CLIENT) + != NGX_OK) + { +- lua_pushnil(L); +- lua_pushliteral(L, "failed to create ssl connection"); +- return 2; ++ *errmsg = "failed to create ssl connection"; ++ return NGX_ERROR; + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { +- return luaL_error(L, "no ctx found"); ++ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ++ "no ngx_lua ctx found while TLS handshaking"); ++ ++ ngx_http_lua_assert(NULL); ++ ++ *errmsg = "no ctx found"; ++ return NGX_ERROR; + } + + coctx = ctx->cur_co_ctx; + + c->sendfile = 0; + +- if (n >= 2) { +- if (lua_type(L, 2) == LUA_TBOOLEAN) { +- u->ssl_session_reuse = lua_toboolean(L, 2); +- +- } else { +- psession = lua_touserdata(L, 2); +- +- if (psession != NULL && *psession != NULL) { +- if (ngx_ssl_set_session(c, *psession) != NGX_OK) { +- lua_pushnil(L); +- lua_pushliteral(L, "lua ssl set session failed"); +- return 2; +- } +- +- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua ssl set session: %p", *psession); +- } ++ if (sess != NULL) { ++ if (ngx_ssl_set_session(c, sess) != NGX_OK) { ++ *errmsg = "lua tls set session failed"; ++ return NGX_ERROR; + } + +- if (n >= 3) { +- name.data = (u_char *) lua_tolstring(L, 3, &name.len); ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, ++ "lua tls set session: %p", sess); + +- if (name.data) { +- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua ssl server name: \"%*s\"", name.len, +- name.data); ++ } else { ++ u->ssl_session_reuse = enable_session_reuse; ++ } + +-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ++ if (server_name != NULL && server_name->data != NULL) { ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "lua tls server name: \"%V\"", server_name); + +- if (SSL_set_tlsext_host_name(c->ssl->connection, +- (char *) name.data) +- == 0) +- { +- lua_pushnil(L); +- lua_pushliteral(L, "SSL_set_tlsext_host_name failed"); +- return 2; +- } ++#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ++ if (SSL_set_tlsext_host_name(c->ssl->connection, ++ (char *) server_name->data) ++ == 0) ++ { ++ *errmsg = "SSL_set_tlsext_host_name failed"; ++ return NGX_ERROR; ++ } + + #else +- +- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua socket SNI disabled because the current " +- "version of OpenSSL lacks the support"); +- ++ *errmsg = "OpenSSL has no SNI support"; ++ return NGX_ERROR; + #endif +- } ++ } + +- if (n >= 4) { +- u->ssl_verify = lua_toboolean(L, 4); ++ u->ssl_verify = verify; + +- if (n >= 5) { +- if (lua_toboolean(L, 5)) { ++ if (ocsp_status_req) { + #ifdef NGX_HTTP_LUA_USE_OCSP +- SSL_set_tlsext_status_type(c->ssl->connection, +- TLSEXT_STATUSTYPE_ocsp); ++ SSL_set_tlsext_status_type(c->ssl->connection, ++ TLSEXT_STATUSTYPE_ocsp); ++ + #else +- return luaL_error(L, "no OCSP support"); ++ *errmsg = "no OCSP support"; ++ return NGX_ERROR; + #endif +- } +- } +- } +- } + } + +- dd("found sni name: %.*s %p", (int) name.len, name.data, name.data); +- +- if (name.len == 0) { ++ if (server_name->len == 0) { + u->ssl_name.len = 0; + + } else { + if (u->ssl_name.data) { + /* buffer already allocated */ + +- if (u->ssl_name.len >= name.len) { ++ if (u->ssl_name.len >= server_name->len) { + /* reuse it */ +- ngx_memcpy(u->ssl_name.data, name.data, name.len); +- u->ssl_name.len = name.len; ++ ngx_memcpy(u->ssl_name.data, server_name->data, server_name->len); ++ u->ssl_name.len = server_name->len; + + } else { + ngx_free(u->ssl_name.data); +@@ -1722,17 +1678,16 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) + + new_ssl_name: + +- u->ssl_name.data = ngx_alloc(name.len, ngx_cycle->log); ++ u->ssl_name.data = ngx_alloc(server_name->len, ngx_cycle->log); + if (u->ssl_name.data == NULL) { + u->ssl_name.len = 0; + +- lua_pushnil(L); +- lua_pushliteral(L, "no memory"); +- return 2; ++ *errmsg = "no memory"; ++ return NGX_ERROR; + } + +- ngx_memcpy(u->ssl_name.data, name.data, name.len); +- u->ssl_name.len = name.len; ++ ngx_memcpy(u->ssl_name.data, server_name->data, server_name->len); ++ u->ssl_name.len = server_name->len; + } + } + +@@ -1746,7 +1701,8 @@ new_ssl_name: + + rc = ngx_ssl_handshake(c); + +- dd("ngx_ssl_handshake returned %d", (int) rc); ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "ngx_ssl_handshake returned %d", rc); + + if (rc == NGX_AGAIN) { + if (c->write->timer_set) { +@@ -1756,13 +1712,13 @@ new_ssl_name: + ngx_add_timer(c->read, u->connect_timeout); + + u->conn_waiting = 1; +- u->write_prepare_retvals = ngx_http_lua_ssl_handshake_retval_handler; ++ u->write_prepare_retvals = ngx_http_lua_tls_handshake_retval_handler; + + ngx_http_lua_cleanup_pending_operation(coctx); + coctx->cleanup = ngx_http_lua_coctx_cleanup; + coctx->data = u; + +- c->ssl->handler = ngx_http_lua_ssl_handshake_handler; ++ c->ssl->handler = ngx_http_lua_tls_handshake_handler; + + if (ctx->entered_content_phase) { + r->write_event_handler = ngx_http_lua_content_wev_handler; +@@ -1771,21 +1727,25 @@ new_ssl_name: + r->write_event_handler = ngx_http_core_run_phases; + } + +- return lua_yield(L, 0); ++ return NGX_AGAIN; ++ } ++ ++ ngx_http_lua_tls_handshake_handler(c); ++ ++ if (rc == NGX_ERROR) { ++ *errmsg = u->error_ret; ++ ++ return NGX_ERROR; + } + +- top = lua_gettop(L); +- ngx_http_lua_ssl_handshake_handler(c); +- return lua_gettop(L) - top; ++ return NGX_OK; + } + + + static void +-ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) ++ngx_http_lua_tls_handshake_handler(ngx_connection_t *c) + { +- const char *err; + int waiting; +- lua_State *L; + ngx_int_t rc; + ngx_connection_t *dc; /* downstream connection */ + ngx_http_request_t *r; +@@ -1808,11 +1768,9 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + waiting = u->conn_waiting; + + dc = r->connection; +- L = u->write_co_ctx->co; + + if (c->read->timedout) { +- lua_pushnil(L); +- lua_pushliteral(L, "timeout"); ++ u->error_ret = "timeout"; + goto failed; + } + +@@ -1821,19 +1779,18 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + } + + if (c->ssl->handshaked) { +- + if (u->ssl_verify) { + rc = SSL_get_verify_result(c->ssl->connection); + + if (rc != X509_V_OK) { +- lua_pushnil(L); +- err = lua_pushfstring(L, "%d: %s", (int) rc, +- X509_verify_cert_error_string(rc)); ++ u->error_ret = X509_verify_cert_error_string(rc); ++ u->openssl_error_code_ret = rc; + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + if (llcf->log_socket_errors) { +- ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " +- "certificate verify error: (%s)", err); ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua tls " ++ "certificate verify error: (%d: %s)", ++ rc, u->error_ret); + } + + goto failed; +@@ -1844,12 +1801,11 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + if (u->ssl_name.len + && ngx_ssl_check_host(c, &u->ssl_name) != NGX_OK) + { +- lua_pushnil(L); +- lua_pushliteral(L, "certificate host mismatch"); ++ u->error_ret = "certificate host mismatch"; + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + if (llcf->log_socket_errors) { +- ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua tls " + "certificate does not match host \"%V\"", + &u->ssl_name); + } +@@ -1864,7 +1820,7 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + ngx_http_lua_socket_handle_conn_success(r, u); + + } else { +- (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, L); ++ (void) ngx_http_lua_tls_handshake_retval_handler(r, u, NULL); + } + + if (waiting) { +@@ -1874,60 +1830,84 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + return; + } + +- lua_pushnil(L); +- lua_pushliteral(L, "handshake failed"); ++ u->error_ret = "handshake failed"; + + failed: + + if (waiting) { + u->write_prepare_retvals = +- ngx_http_lua_socket_conn_error_retval_handler; +- ngx_http_lua_socket_handle_conn_error(r, u, +- NGX_HTTP_LUA_SOCKET_FT_SSL); ++ ngx_http_lua_socket_conn_error_retval_handler; ++ ngx_http_lua_socket_handle_conn_error(r, u, NGX_HTTP_LUA_SOCKET_FT_SSL); + ngx_http_run_posted_requests(dc); + + } else { +- (void) ngx_http_lua_socket_conn_error_retval_handler(r, u, L); ++ u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_SSL; ++ ++ (void) ngx_http_lua_socket_conn_error_retval_handler(r, u, NULL); + } + } + + ++ ++int ++ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, ++ ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t **sess, ++ const char **errmsg, int *openssl_error_code) ++{ ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "lua cosocket get TLS handshake result for upstream: %p", u); ++ ++ if (u->error_ret != NULL) { ++ *errmsg = u->error_ret; ++ *openssl_error_code = u->openssl_error_code_ret; ++ ++ return NGX_ERROR; ++ } ++ ++ *sess = u->ssl_session_ret; ++ ++ return NGX_OK; ++} ++ ++ + static int +-ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, ++ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L) + { + ngx_connection_t *c; +- ngx_ssl_session_t *ssl_session, **ud; ++ ngx_ssl_session_t *ssl_session; + + if (!u->ssl_session_reuse) { +- lua_pushboolean(L, 1); +- return 1; ++ return 0; + } + +- ud = lua_newuserdata(L, sizeof(ngx_ssl_session_t *)); +- + c = u->peer.connection; + + ssl_session = ngx_ssl_get_session(c); + if (ssl_session == NULL) { +- *ud = NULL; ++ u->ssl_session_ret = NULL; + + } else { +- *ud = ssl_session; ++ u->ssl_session_ret = ssl_session; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua ssl save session: %p", ssl_session); +- +- /* set up the __gc metamethod */ +- lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( +- ssl_session_metatable_key)); +- lua_rawget(L, LUA_REGISTRYINDEX); +- lua_setmetatable(L, -2); ++ "lua tls save session: %p", ssl_session); + } + +- return 1; ++ return 0; + } + ++ ++void ++ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess) ++{ ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, ++ "lua tls free session: %p", sess); ++ ++ ngx_ssl_free_session(sess); ++} ++ ++ + #endif /* NGX_HTTP_SSL */ + + +@@ -1980,12 +1960,14 @@ ngx_http_lua_socket_prepare_error_retvals(ngx_http_request_t *r, + u_char errstr[NGX_MAX_ERROR_STR]; + u_char *p; + +- if (ft_type & (NGX_HTTP_LUA_SOCKET_FT_RESOLVER +- | NGX_HTTP_LUA_SOCKET_FT_SSL)) +- { ++ if (ft_type & NGX_HTTP_LUA_SOCKET_FT_RESOLVER) { + return 2; + } + ++ if (ft_type & NGX_HTTP_LUA_SOCKET_FT_SSL) { ++ return 0; ++ } ++ + lua_pushnil(L); + + if (ft_type & NGX_HTTP_LUA_SOCKET_FT_TIMEOUT) { +@@ -6057,27 +6039,6 @@ ngx_http_lua_coctx_cleanup(void *data) + } + + +-#if (NGX_HTTP_SSL) +- +-static int +-ngx_http_lua_ssl_free_session(lua_State *L) +-{ +- ngx_ssl_session_t **psession; +- +- psession = lua_touserdata(L, 1); +- if (psession && *psession != NULL) { +- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, +- "lua ssl free session: %p", *psession); +- +- ngx_ssl_free_session(*psession); +- } +- +- return 0; +-} +- +-#endif /* NGX_HTTP_SSL */ +- +- + void + ngx_http_lua_cleanup_conn_pools(lua_State *L) + { +diff --git a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.h b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.h +index 091e4378..bb618702 100644 +--- a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.h ++++ b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.h +@@ -114,6 +114,9 @@ struct ngx_http_lua_socket_tcp_upstream_s { + + #if (NGX_HTTP_SSL) + ngx_str_t ssl_name; ++ ngx_ssl_session_t *ssl_session_ret; ++ const char *error_ret; ++ int openssl_error_code_ret; + #endif + + unsigned ft_type:16; +-- +2.20.1 + + +From 265b94ffd2158bea727fcd0bedb467268461ebae Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:54:32 -0700 +Subject: change: better error when request context couldn't be found. + +--- + ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +index 1e3fc91f..43759e91 100644 +--- a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +@@ -1599,13 +1599,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { +- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, +- "no ngx_lua ctx found while TLS handshaking"); +- +- ngx_http_lua_assert(NULL); +- +- *errmsg = "no ctx found"; +- return NGX_ERROR; ++ return NGX_HTTP_LUA_FFI_NO_REQ_CTX; + } + + coctx = ctx->cur_co_ctx; +-- +2.20.1 + + +From 60dfb155c4d0e0855c4777ee574428ad9e60fbef Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:24:07 -0700 +Subject: feature: TCP cosocket client certificate support. closes #534 + +--- + ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c | 60 ++++++- + 8 files changed, 732 insertions(+), 8 deletions(-) + +diff --git a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +index 43759e91..02f4e84a 100644 +--- a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +@@ -22,7 +22,6 @@ + static int ngx_http_lua_socket_tcp(lua_State *L); + static int ngx_http_lua_socket_tcp_connect(lua_State *L); + #if (NGX_HTTP_SSL) +-static int ngx_http_lua_socket_tcp_sslhandshake(lua_State *L); + static void ngx_http_lua_tls_handshake_handler(ngx_connection_t *c); + static int ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); +@@ -213,9 +212,6 @@ static char ngx_http_lua_upstream_udata_metatable_key; + static char ngx_http_lua_downstream_udata_metatable_key; + static char ngx_http_lua_pool_udata_metatable_key; + static char ngx_http_lua_pattern_udata_metatable_key; +-#if (NGX_HTTP_SSL) +-static char ngx_http_lua_ssl_session_metatable_key; +-#endif + + + void +@@ -1535,13 +1531,16 @@ int + ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, + int enable_session_reuse, ngx_str_t *server_name, int verify, +- int ocsp_status_req, const char **errmsg) ++ int ocsp_status_req, STACK_OF(X509) *chain, EVP_PKEY *pkey, ++ const char **errmsg) + { +- ngx_int_t rc; ++ ngx_int_t rc, i; + ngx_connection_t *c; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_co_ctx_t *coctx; + const char *busy_rc; ++ ngx_ssl_conn_t *ssl_conn; ++ X509 *x509; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket tls handshake"); +@@ -1597,6 +1596,8 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + return NGX_ERROR; + } + ++ ssl_conn = c->ssl->connection; ++ + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return NGX_HTTP_LUA_FFI_NO_REQ_CTX; +@@ -1619,6 +1620,53 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + u->ssl_session_reuse = enable_session_reuse; + } + ++ if (chain != NULL) { ++ ngx_http_lua_assert(pkey != NULL); /* ensured by resty.core */ ++ ++ if (sk_X509_num(chain) < 1) { ++ ERR_clear_error(); ++ *errmsg = "invalid client certificate chain"; ++ return NGX_ERROR; ++ } ++ ++ x509 = sk_X509_value(chain, 0); ++ if (x509 == NULL) { ++ ERR_clear_error(); ++ *errmsg = "lua tls fetch client certificate from chain failed"; ++ return NGX_ERROR; ++ } ++ ++ if (SSL_use_certificate(ssl_conn, x509) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua tls set client certificate failed"; ++ return NGX_ERROR; ++ } ++ ++ /* read rest of the chain */ ++ ++ for (i = 1; i < sk_X509_num(chain); i++) { ++ x509 = sk_X509_value(chain, i); ++ if (x509 == NULL) { ++ ERR_clear_error(); ++ *errmsg = "lua tls fetch client intermediate certificate " ++ "from chain failed"; ++ return NGX_ERROR; ++ } ++ ++ if (SSL_add1_chain_cert(ssl_conn, x509) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua tls set client intermediate certificate failed"; ++ return NGX_ERROR; ++ } ++ } ++ ++ if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua ssl set client private key failed"; ++ return NGX_ERROR; ++ } ++ } ++ + if (server_name != NULL && server_name->data != NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tls server name: \"%V\"", server_name); +-- +2.20.1 + + +From a94bfb87da1f549c56d13288dcef102ee043b2a4 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:25:20 -0700 +Subject: style: style fixes. + +--- + ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +index 02f4e84a..b5954c7d 100644 +--- a/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.15/src/ngx_http_lua_socket_tcp.c +@@ -1708,7 +1708,8 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + if (u->ssl_name.len >= server_name->len) { + /* reuse it */ +- ngx_memcpy(u->ssl_name.data, server_name->data, server_name->len); ++ ngx_memcpy(u->ssl_name.data, server_name->data, ++ server_name->len); + u->ssl_name.len = server_name->len; + + } else { +-- +2.20.1 +