Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions lib/resty/core/socket.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ local option_index = {
local ngx_lua_ffi_socket_tcp_getoption
local ngx_lua_ffi_socket_tcp_setoption
local ngx_lua_ffi_socket_getfd
local ngx_lua_ffi_socket_getsslpointer
local ngx_lua_ffi_socket_getsslctx

if subsystem == 'http' then
ffi.cdef[[
Expand Down Expand Up @@ -75,11 +77,21 @@ int
ngx_http_lua_socket_tcp_get_ssl_session(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, void **sess,
char **errmsg);
int
ngx_http_lua_ffi_socket_tcp_get_ssl_pointer(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, void **pssl,
char **errmsg);
int
ngx_http_lua_ffi_socket_tcp_get_ssl_ctx(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, void **pctx,
char **errmsg);
]]

ngx_lua_ffi_socket_tcp_getoption = C.ngx_http_lua_ffi_socket_tcp_getoption
ngx_lua_ffi_socket_tcp_setoption = C.ngx_http_lua_ffi_socket_tcp_setoption
ngx_lua_ffi_socket_getfd = C.ngx_http_lua_ffi_socket_tcp_getfd
ngx_lua_ffi_socket_getsslpointer = C.ngx_http_lua_ffi_socket_tcp_get_ssl_pointer
ngx_lua_ffi_socket_getsslctx = C.ngx_http_lua_ffi_socket_tcp_get_ssl_ctx

elseif subsystem == 'stream' then

Expand All @@ -97,11 +109,21 @@ int
ngx_stream_lua_ffi_socket_tcp_getfd(ngx_stream_lua_request_t *r,
ngx_stream_lua_socket_tcp_upstream_t *u,
char **errmsg);
int
ngx_stream_lua_ffi_socket_tcp_get_ssl_pointer(ngx_stream_lua_request_t *r,
ngx_stream_lua_socket_tcp_upstream_t *u, void **pssl,
char **errmsg);
int
ngx_stream_lua_ffi_socket_tcp_get_ssl_ctx(ngx_stream_lua_request_t *r,
ngx_stream_lua_socket_tcp_upstream_t *u, void **pctx,
char **errmsg);
]]

ngx_lua_ffi_socket_tcp_getoption = C.ngx_stream_lua_ffi_socket_tcp_getoption
ngx_lua_ffi_socket_tcp_setoption = C.ngx_stream_lua_ffi_socket_tcp_setoption
ngx_lua_ffi_socket_getfd = C.ngx_stream_lua_ffi_socket_tcp_getfd
ngx_lua_ffi_socket_getsslpointer = C.ngx_stream_lua_ffi_socket_tcp_get_ssl_pointer
ngx_lua_ffi_socket_getsslctx = C.ngx_stream_lua_ffi_socket_tcp_get_ssl_ctx
end


Expand Down Expand Up @@ -215,6 +237,49 @@ local function getfd(cosocket)
end


local function getsslpointer(cosocket)
if not cosocket then
error("ngx.socket getfd: expecting the cosocket object, but seen none")
end

local r = get_request()
if not r then
error("no request found")
end

local u = get_tcp_socket(cosocket)
local rc = ngx_lua_ffi_socket_getsslpointer(r, u,
session_ptr, errmsg)
if rc == FFI_ERROR then
return nil, ffi_str(errmsg[0])
end

return session_ptr[0]
end


local function getsslctx(cosocket)
if not cosocket then
error("ngx.socket getfd: expecting the cosocket object, but seen none")
end

local r = get_request()
if not r then
error("no request found")
end

local u = get_tcp_socket(cosocket)
local rc = ngx_lua_ffi_socket_getsslctx(r, u,
session_ptr, errmsg)
if rc == FFI_ERROR then
return nil, ffi_str(errmsg[0])
end

return session_ptr[0]
end



if subsystem == 'http' then
local server_name_str = ffi_new("ngx_str_t[1]")
local openssl_error_code = ffi_new("int[1]")
Expand Down Expand Up @@ -358,6 +423,7 @@ local function getsslsession(cosocket)
return ffi_gc(session_ptr[0], C.ngx_http_lua_ffi_ssl_free_session)
end


do
local method_table = registry.__tcp_cosocket_mt
method_table.getoption = getoption
Expand All @@ -368,6 +434,8 @@ do
method_table.getoption = getoption
method_table.setoption = setoption
method_table.getsslsession = getsslsession
method_table.getsslpointer = getsslpointer
method_table.getsslctx = getsslctx

method_table = registry.__tcp_req_cosocket_mt
method_table.getfd = getfd
Expand All @@ -386,6 +454,8 @@ do
method_table.getoption = getoption
method_table.setoption = setoption
method_table.getfd = getfd
method_table.getsslpointer = getsslpointer
method_table.getsslctx = getsslctx

method_table = registry.__tcp_raw_req_cosocket_mt
method_table.getfd = getfd
Expand Down
97 changes: 97 additions & 0 deletions t/ssl.t
Original file line number Diff line number Diff line change
Expand Up @@ -3545,3 +3545,100 @@ qr/upstream ssl state: (false|true)/
[error]
[emerg]
[crit]



=== TEST 37: get cosocket SSL pointer
--- http_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";

server {
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
server_name test.com;
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;

server_tokens off;
location /foo {
default_type 'text/plain';
content_by_lua_block {ngx.status = 201 ngx.say("foo") ngx.exit(201)}
more_clear_headers Date;
}
}
--- config
server_tokens off;
lua_ssl_trusted_certificate ../../cert/test.crt;

location /t {
content_by_lua_block {
do
local sock = ngx.socket.tcp()

sock:settimeout(3000)

local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock")
if not ok then
ngx.say("failed to connect: ", err)
return
end

ngx.say("connected: ", ok)

local sess, err = sock:sslhandshake(nil, "test.com", true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end

ngx.say("ssl handshake: ", type(sess))
ngx.say("ssl pointer: ", type(sock:getsslpointer()))
ngx.say("ssl ctx: ", type(sock:getsslctx()))

local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n"
local bytes, err = sock:send(req)
if not bytes then
ngx.say("failed to send http request: ", err)
return
end

ngx.say("sent http request: ", bytes, " bytes.")

while true do
local line, err = sock:receive()
if not line then
-- ngx.say("failed to receive response status line: ", err)
break
end

ngx.say("received: ", line)
end

local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end -- do
-- collectgarbage()
}
}

--- request
GET /t
--- response_body
connected: 1
ssl handshake: cdata
ssl pointer: cdata
ssl ctx: cdata
sent http request: 56 bytes.
received: HTTP/1.1 201 Created
received: Server: nginx
received: Content-Type: text/plain
received: Content-Length: 4
received: Connection: close
received:
received: foo
close: 1 nil
--- error_log
lua ssl server name: "test.com"
--- no_error_log
[error]
[emerg]
[crit]
75 changes: 75 additions & 0 deletions t/stream/ssl.t
Original file line number Diff line number Diff line change
Expand Up @@ -2552,3 +2552,78 @@ qr/session reused: false/
[alert]
[crit]
[error]



=== TEST 32: get cosocet SSL pointer
--- stream_config
lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH";

server {
listen 127.0.0.1:$TEST_NGINX_RAND_PORT_1 ssl;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_certificate ../../cert/test.crt;
ssl_certificate_key ../../cert/test.key;

return 'it works!\n';
}
--- stream_server_config
lua_ssl_trusted_certificate ../../cert/test.crt;
lua_ssl_protocols TLSv1.2;
lua_ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256;

content_by_lua_block {
do
local sock = ngx.socket.tcp()

sock:settimeout(3000)

local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_RAND_PORT_1)
if not ok then
ngx.say("failed to connect: ", err)
return
end

ngx.say("connected: ", ok)

local sess, err = sock:sslhandshake(nil, nil, true)
if not sess then
ngx.say("failed to do SSL handshake: ", err)
return
end

ngx.say("ssl session: ", type(sess))
ngx.say("ssl pointer: ", type(sock:getsslpointer()))
ngx.say("ssl ctx: ", type(sock:getsslctx()))
ngx.log(ngx.INFO, "ssl pointer: ", tostring(sock:getsslpointer()))

while true do
local line, err = sock:receive()
if not line then
-- ngx.say("failed to receive response status line: ", err)
break
end

ngx.say("received: ", line)
end

local ok, err = sock:close()
ngx.say("close: ", ok, " ", err)
end -- do
-- collectgarbage()
}

--- stream_response
connected: 1
ssl session: userdata
ssl pointer: cdata
ssl ctx: cdata
received: it works!
close: 1 nil
--- error_log eval
qr/ssl pointer: cdata<void \*>: 0x[0-9a-f]+,/
--- no_error_log
[alert]
[crit]
[error]