mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Squashed 'src/deps/src/stream-lua-nginx-module/' changes from cafa6f553..bea8a0c0d
bea8a0c0d bugfix: Check for SSL context instead of listen. cb82db357 bugfix: wrong arguments of setkeepalive() result in the compromise of data integrity. a5c924b02 bugfix: correct offset vector memory allocation size for PCRE2. ff9dea82f feature: add ngx_stream_lua_ffi_ssl_client_random. fd136cc41 bugfix: wrong argument for pcre2_match. af96930ba feature: add functions to parse DER formatted certificates/keys. f1499e3b0 changes: remove the useless pcre config. git-subtree-dir: src/deps/src/stream-lua-nginx-module git-subtree-split: bea8a0c0de94cede71554f53818ac0267d675d63
This commit is contained in:
parent
28b42bd400
commit
530d65989a
10 changed files with 605 additions and 78 deletions
39
config
39
config
|
|
@ -405,45 +405,6 @@ fi
|
|||
|
||||
# ----------------------------------------
|
||||
|
||||
if [ $USE_PCRE = YES -o $PCRE != NONE ] && [ $PCRE != NO -a $PCRE != YES ] && [ $PCRE2 != YES ]; then
|
||||
# force pcre_version symbol to be required when PCRE is statically linked
|
||||
case "$NGX_PLATFORM" in
|
||||
Darwin:*)
|
||||
ngx_feature="require defined symbols (-u)"
|
||||
ngx_feature_name=
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs="-Wl,-u,_strerror"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <stdio.h>"
|
||||
ngx_feature_test='printf("hello");'
|
||||
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
CORE_LIBS="-Wl,-u,_pcre_version $CORE_LIBS"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
ngx_feature="require defined symbols (--require-defined)"
|
||||
ngx_feature_name=
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs="-Wl,--require-defined=strerror"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <stdio.h>"
|
||||
ngx_feature_test='printf("hello");'
|
||||
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
CORE_LIBS="-Wl,--require-defined=pcre_version $CORE_LIBS"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ----------------------------------------
|
||||
|
||||
USE_MD5=YES
|
||||
USE_SHA1=YES
|
||||
|
||||
|
|
|
|||
|
|
@ -864,12 +864,20 @@ ngx_stream_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_stream_lua_srv_conf_t *conf = child;
|
||||
|
||||
#if (NGX_STREAM_SSL)
|
||||
#if defined(nginx_version) && nginx_version >= 1025005
|
||||
ngx_stream_ssl_srv_conf_t *sscf;
|
||||
#else
|
||||
ngx_stream_ssl_conf_t *sscf;
|
||||
#endif
|
||||
|
||||
dd("merge srv conf");
|
||||
|
||||
sscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_ssl_module);
|
||||
#if defined(nginx_version) && nginx_version >= 1025005
|
||||
if (sscf && sscf->ssl.ctx) {
|
||||
#else
|
||||
if (sscf && sscf->listen) {
|
||||
#endif
|
||||
if (conf->srv.ssl_client_hello_src.len == 0) {
|
||||
conf->srv.ssl_client_hello_src = prev->srv.ssl_client_hello_src;
|
||||
conf->srv.ssl_client_hello_src_key =
|
||||
|
|
|
|||
|
|
@ -598,7 +598,11 @@ ngx_stream_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
|
|||
re_comp.captures = 0;
|
||||
|
||||
} else {
|
||||
#if (NGX_PCRE2)
|
||||
ovecsize = (re_comp.captures + 1) * 2;
|
||||
#else
|
||||
ovecsize = (re_comp.captures + 1) * 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
dd("allocating cap with size: %d", (int) ovecsize);
|
||||
|
|
@ -691,21 +695,21 @@ ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags,
|
|||
{
|
||||
int rc, exec_opts = 0;
|
||||
size_t *ov;
|
||||
ngx_uint_t ovecsize, n, i;
|
||||
ngx_uint_t ovecpair, n, i;
|
||||
ngx_pool_t *old_pool;
|
||||
|
||||
if (flags & NGX_LUA_RE_MODE_DFA) {
|
||||
ovecsize = 2;
|
||||
ovecpair = 1;
|
||||
re->ncaptures = 0;
|
||||
|
||||
} else {
|
||||
ovecsize = (re->ncaptures + 1) * 3;
|
||||
ovecpair = re->ncaptures + 1;
|
||||
}
|
||||
|
||||
old_pool = ngx_stream_lua_pcre_malloc_init(NULL);
|
||||
|
||||
if (ngx_regex_match_data == NULL
|
||||
|| ovecsize > ngx_regex_match_data_size)
|
||||
|| ovecpair > ngx_regex_match_data_size)
|
||||
{
|
||||
/*
|
||||
* Allocate a match data if not yet allocated or smaller than
|
||||
|
|
@ -716,8 +720,8 @@ ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags,
|
|||
pcre2_match_data_free(ngx_regex_match_data);
|
||||
}
|
||||
|
||||
ngx_regex_match_data_size = ovecsize;
|
||||
ngx_regex_match_data = pcre2_match_data_create(ovecsize / 3, NULL);
|
||||
ngx_regex_match_data_size = ovecpair;
|
||||
ngx_regex_match_data = pcre2_match_data_create(ovecpair, NULL);
|
||||
|
||||
if (ngx_regex_match_data == NULL) {
|
||||
rc = PCRE2_ERROR_NOMEMORY;
|
||||
|
|
@ -747,7 +751,7 @@ ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags,
|
|||
#if (NGX_DEBUG)
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0,
|
||||
"pcre2_match failed: flags 0x%05Xd, options 0x%08Xd, rc %d, "
|
||||
"ovecsize %ui", flags, exec_opts, rc, ovecsize);
|
||||
"ovecpair %ui", flags, exec_opts, rc, ovecpair);
|
||||
#endif
|
||||
|
||||
goto failed;
|
||||
|
|
@ -759,11 +763,11 @@ ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags,
|
|||
#if (NGX_DEBUG)
|
||||
ngx_log_debug5(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0,
|
||||
"pcre2_match: flags 0x%05Xd, options 0x%08Xd, rc %d, "
|
||||
"n %ui, ovecsize %ui", flags, exec_opts, rc, n, ovecsize);
|
||||
"n %ui, ovecpair %ui", flags, exec_opts, rc, n, ovecpair);
|
||||
#endif
|
||||
|
||||
if (!(flags & NGX_LUA_RE_MODE_DFA) && n > ovecsize / 3) {
|
||||
n = ovecsize / 3;
|
||||
if (n > ovecpair) {
|
||||
n = ovecpair;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
|
|
@ -796,6 +800,21 @@ ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags,
|
|||
re->ncaptures = 0;
|
||||
|
||||
} else {
|
||||
/* How pcre_exec() returns captured substrings
|
||||
* The first two-thirds of the vector is used to pass back captured
|
||||
* substrings, each substring using a pair of integers. The remaining
|
||||
* third of the vector is used as workspace by pcre_exec() while
|
||||
* matching capturing subpatterns, and is not available for passing
|
||||
* back information. The number passed in ovecsize should always be a
|
||||
* multiple of three. If it is not, it is rounded down.
|
||||
*
|
||||
* When a match is successful, information about captured substrings is
|
||||
* returned in pairs of integers, starting at the beginning of ovector,
|
||||
* and continuing up to two-thirds of its length at the most. The first
|
||||
* element of each pair is set to the byte offset of the first character
|
||||
* in a substring, and the second is set to the byte offset of the first
|
||||
* character after the end of a substring.
|
||||
*/
|
||||
ovecsize = (re->ncaptures + 1) * 3;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5250,6 +5250,34 @@ ngx_stream_lua_socket_tcp_setkeepalive(lua_State *L)
|
|||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
|
||||
r = ngx_stream_lua_get_req(L);
|
||||
if (r == NULL) {
|
||||
return luaL_error(L, "no request found");
|
||||
}
|
||||
|
||||
llcf = ngx_stream_lua_get_module_loc_conf(r, ngx_stream_lua_module);
|
||||
|
||||
/* luaL_checkinteger will throw error if the argument is not a number.
|
||||
* e.g.: bad argument \#2 to '?' (number expected, got string)
|
||||
*
|
||||
* We should check the argument in advance; otherwise,
|
||||
* throwing an exception in the middle can compromise data integrity.
|
||||
* e.g.: set pc->connection to NULL without following cleanup.
|
||||
*/
|
||||
if (n >= 2 && !lua_isnil(L, 2)) {
|
||||
timeout = (ngx_msec_t) luaL_checkinteger(L, 2);
|
||||
|
||||
} else {
|
||||
timeout = llcf->keepalive_timeout;
|
||||
}
|
||||
|
||||
if (n >= 3 && !lua_isnil(L, 3)) {
|
||||
pool_size = luaL_checkinteger(L, 3);
|
||||
|
||||
} else {
|
||||
pool_size = llcf->pool_size;
|
||||
}
|
||||
|
||||
lua_rawgeti(L, 1, SOCKET_CTX_INDEX);
|
||||
u = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
|
@ -5271,11 +5299,6 @@ ngx_stream_lua_socket_tcp_setkeepalive(lua_State *L)
|
|||
return 2;
|
||||
}
|
||||
|
||||
r = ngx_stream_lua_get_req(L);
|
||||
if (r == NULL) {
|
||||
return luaL_error(L, "no request found");
|
||||
}
|
||||
|
||||
if (u->request != r) {
|
||||
return luaL_error(L, "bad request");
|
||||
}
|
||||
|
|
@ -5349,18 +5372,9 @@ ngx_stream_lua_socket_tcp_setkeepalive(lua_State *L)
|
|||
|
||||
/* stack: obj timeout? size? pools cache_key */
|
||||
|
||||
llcf = ngx_stream_lua_get_module_loc_conf(r, ngx_stream_lua_module);
|
||||
|
||||
if (spool == NULL) {
|
||||
/* create a new socket pool for the current peer key */
|
||||
|
||||
if (n >= 3 && !lua_isnil(L, 3)) {
|
||||
pool_size = luaL_checkinteger(L, 3);
|
||||
|
||||
} else {
|
||||
pool_size = llcf->pool_size;
|
||||
}
|
||||
|
||||
if (pool_size <= 0) {
|
||||
msg = lua_pushfstring(L, "bad \"pool_size\" option value: %i",
|
||||
pool_size);
|
||||
|
|
@ -5425,13 +5439,6 @@ ngx_stream_lua_socket_tcp_setkeepalive(lua_State *L)
|
|||
ngx_del_timer(c->write);
|
||||
}
|
||||
|
||||
if (n >= 2 && !lua_isnil(L, 2)) {
|
||||
timeout = (ngx_msec_t) luaL_checkinteger(L, 2);
|
||||
|
||||
} else {
|
||||
timeout = llcf->keepalive_timeout;
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
if (timeout == 0) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, r->connection->log, 0,
|
||||
|
|
|
|||
|
|
@ -986,8 +986,8 @@ ngx_stream_lua_ffi_ssl_raw_client_addr(ngx_stream_lua_request_t *r, char **addr,
|
|||
|
||||
|
||||
int
|
||||
ngx_stream_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len, u_char *der,
|
||||
char **err)
|
||||
ngx_stream_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len,
|
||||
u_char *der, char **err)
|
||||
{
|
||||
int total, len;
|
||||
BIO *bio;
|
||||
|
|
@ -1079,7 +1079,7 @@ ngx_stream_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, (void *)passphrase);
|
||||
pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, (void *) passphrase);
|
||||
if (pkey == NULL) {
|
||||
BIO_free(in);
|
||||
*err = "PEM_read_bio_PrivateKey() failed";
|
||||
|
|
@ -1186,6 +1186,75 @@ ngx_stream_lua_ffi_parse_pem_cert(const u_char *pem, size_t pem_len,
|
|||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_stream_lua_ffi_parse_der_cert(const char *data, size_t len,
|
||||
char **err)
|
||||
{
|
||||
BIO *bio;
|
||||
X509 *x509;
|
||||
STACK_OF(X509) *chain;
|
||||
|
||||
bio = BIO_new_mem_buf((char *) data, len);
|
||||
if (bio == NULL) {
|
||||
*err = "BIO_new_mem_buf() failed";
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
x509 = d2i_X509_bio(bio, NULL);
|
||||
if (x509 == NULL) {
|
||||
*err = "d2i_X509_bio() failed";
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chain = sk_X509_new_null();
|
||||
if (chain == NULL) {
|
||||
*err = "sk_X509_new_null() failed";
|
||||
X509_free(x509);
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sk_X509_push(chain, x509) == 0) {
|
||||
*err = "sk_X509_push() failed";
|
||||
sk_X509_free(chain);
|
||||
X509_free(x509);
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read rest of the chain */
|
||||
|
||||
while (!BIO_eof(bio)) {
|
||||
x509 = d2i_X509_bio(bio, NULL);
|
||||
if (x509 == NULL) {
|
||||
*err = "d2i_X509_bio() failed in rest of chain";
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sk_X509_push(chain, x509) == 0) {
|
||||
*err = "sk_X509_push() failed in rest of chain";
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
X509_free(x509);
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_stream_lua_ffi_free_cert(void *cdata)
|
||||
{
|
||||
|
|
@ -1223,6 +1292,35 @@ ngx_stream_lua_ffi_parse_pem_priv_key(const u_char *pem, size_t pem_len,
|
|||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_stream_lua_ffi_parse_der_priv_key(const char *data, size_t len,
|
||||
char **err)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
bio = BIO_new_mem_buf((char *) data, len);
|
||||
if (bio == NULL) {
|
||||
*err = "BIO_new_mem_buf() failed";
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pkey = d2i_PrivateKey_bio(bio, NULL);
|
||||
if (pkey == NULL) {
|
||||
*err = "d2i_PrivateKey_bio() failed";
|
||||
BIO_free(bio);
|
||||
ERR_clear_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_stream_lua_ffi_free_priv_key(void *cdata)
|
||||
{
|
||||
|
|
@ -1385,7 +1483,11 @@ ngx_stream_lua_ffi_ssl_verify_client(ngx_stream_lua_request_t *r,
|
|||
|
||||
ngx_stream_lua_ctx_t *ctx;
|
||||
ngx_ssl_conn_t *ssl_conn;
|
||||
#if defined(nginx_version) && nginx_version >= 1025005
|
||||
ngx_stream_ssl_srv_conf_t *sscf;
|
||||
#else
|
||||
ngx_stream_ssl_conf_t *sscf;
|
||||
#endif
|
||||
STACK_OF(X509) *chain = ca_certs;
|
||||
STACK_OF(X509_NAME) *name_chain = NULL;
|
||||
X509 *x509 = NULL;
|
||||
|
|
@ -1505,4 +1607,27 @@ failed:
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
ngx_stream_lua_ffi_ssl_client_random(ngx_stream_lua_request_t *r,
|
||||
unsigned char *out, size_t *outlen, char **err)
|
||||
{
|
||||
ngx_ssl_conn_t *ssl_conn;
|
||||
|
||||
if (r->connection == NULL || r->connection->ssl == NULL) {
|
||||
*err = "bad request";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ssl_conn = r->connection->ssl->connection;
|
||||
if (ssl_conn == NULL) {
|
||||
*err = "bad ssl conn";
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*outlen = SSL_get_client_random(ssl_conn, out, *outlen);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NGX_STREAM_SSL */
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ __DATA__
|
|||
=== TEST 1: matched with d
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
m = ngx.re.match("hello", "(he|hell)", "d")
|
||||
local m = ngx.re.match("hello", "(he|hell)", "d")
|
||||
if m then
|
||||
ngx.say(m[0])
|
||||
else
|
||||
|
|
@ -34,7 +34,7 @@ hell
|
|||
=== TEST 2: matched with d + j
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
m = ngx.re.match("hello", "(he|hell)", "jd")
|
||||
local m = ngx.re.match("hello", "(he|hell)", "jd")
|
||||
if m then
|
||||
ngx.say(m[0])
|
||||
else
|
||||
|
|
@ -49,7 +49,7 @@ hell
|
|||
=== TEST 3: not matched with j
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
m = ngx.re.match("world", "(he|hell)", "d")
|
||||
local m = ngx.re.match("world", "(he|hell)", "d")
|
||||
if m then
|
||||
ngx.say(m[0])
|
||||
else
|
||||
|
|
@ -64,7 +64,7 @@ not matched!
|
|||
=== TEST 4: matched with do
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
m = ngx.re.match("hello", "he|hell", "do")
|
||||
local m = ngx.re.match("hello", "he|hell", "do")
|
||||
if m then
|
||||
ngx.say(m[0])
|
||||
ngx.say(m[1])
|
||||
|
|
@ -83,7 +83,7 @@ nil
|
|||
=== TEST 5: not matched with do
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
m = ngx.re.match("world", "([0-9]+)", "do")
|
||||
local m = ngx.re.match("world", "([0-9]+)", "do")
|
||||
if m then
|
||||
ngx.say(m[0])
|
||||
else
|
||||
|
|
@ -152,3 +152,26 @@ exec opts: 0
|
|||
你
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 8: matched dfa after nfa
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
local m1 = ngx.re.match("hello", "(a)(a)(a)")
|
||||
if m1 then
|
||||
ngx.say(m1[0])
|
||||
else
|
||||
ngx.say("not matched!")
|
||||
end
|
||||
|
||||
local m2 = ngx.re.match("world", "w", "d")
|
||||
if m2 then
|
||||
ngx.say(m2[0])
|
||||
else
|
||||
ngx.say("not matched!")
|
||||
end
|
||||
}
|
||||
--- stream_response
|
||||
not matched!
|
||||
w
|
||||
|
|
|
|||
|
|
@ -2354,3 +2354,141 @@ ok
|
|||
lua tcp socket abort queueing
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 53: wrong first argument of setkeepalive()
|
||||
--- config
|
||||
location /foo {
|
||||
server_tokens off;
|
||||
keepalive_timeout 60s;
|
||||
echo foo;
|
||||
}
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
local sock = ngx.socket.tcp()
|
||||
sock:settimeouts(1000, 1000, 1000)
|
||||
|
||||
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("connected: ", ok)
|
||||
|
||||
local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n"
|
||||
|
||||
local bytes, err = sock:send(req)
|
||||
if not bytes then
|
||||
ngx.say("failed to send request: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("request sent: ", bytes)
|
||||
|
||||
local reader = sock:receiveuntil("\r\n0\r\n\r\n")
|
||||
local data, err = reader()
|
||||
if not data then
|
||||
ngx.say("failed to receive response body: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("received response of ", #data, " bytes")
|
||||
|
||||
local ok, err = sock:setkeepalive()
|
||||
if not ok then
|
||||
ngx.say("failed to set reusable: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = sock:setkeepalive("not a number")
|
||||
if not ok then
|
||||
ngx.say("failed to set reusable: ", err)
|
||||
return
|
||||
end
|
||||
}
|
||||
--- stream_response
|
||||
connected: 1
|
||||
request sent: 61
|
||||
received response of 156 bytes
|
||||
--- error_log eval
|
||||
qr/\Qbad argument #1 to 'setkeepalive' (number expected, got string)\E/
|
||||
--- no_error_log
|
||||
[crit]
|
||||
--- timeout: 4
|
||||
|
||||
|
||||
|
||||
=== TEST 54: wrong second argument of setkeepalive()
|
||||
--- config
|
||||
location /foo {
|
||||
server_tokens off;
|
||||
keepalive_timeout 60s;
|
||||
echo foo;
|
||||
}
|
||||
--- stream_server_config
|
||||
content_by_lua_block {
|
||||
local sock = ngx.socket.tcp()
|
||||
sock:settimeouts(1000, 1000, 1000)
|
||||
|
||||
local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("connected: ", ok)
|
||||
|
||||
local req = "GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n"
|
||||
|
||||
local bytes, err = sock:send(req)
|
||||
if not bytes then
|
||||
ngx.say("failed to send request: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("request sent: ", bytes)
|
||||
|
||||
local reader = sock:receiveuntil("\r\n0\r\n\r\n")
|
||||
local data, err = reader()
|
||||
if not data then
|
||||
ngx.say("failed to receive response body: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("received response of ", #data, " bytes")
|
||||
|
||||
local ok, err = sock:setkeepalive()
|
||||
if not ok then
|
||||
ngx.say("failed to set reusable: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT)
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = sock:setkeepalive(10, "not a number")
|
||||
if not ok then
|
||||
ngx.say("failed to set reusable: ", err)
|
||||
return
|
||||
end
|
||||
}
|
||||
--- stream_response
|
||||
connected: 1
|
||||
request sent: 61
|
||||
received response of 156 bytes
|
||||
--- error_log eval
|
||||
qr/\Qbad argument #2 to 'setkeepalive' (number expected, got string)\E/
|
||||
--- no_error_log
|
||||
[crit]
|
||||
--- timeout: 4
|
||||
|
|
|
|||
|
|
@ -48,9 +48,15 @@ ffi.cdef[[
|
|||
void *ngx_stream_lua_ffi_parse_pem_cert(const unsigned char *pem,
|
||||
size_t pem_len, char **err);
|
||||
|
||||
void *ngx_stream_lua_ffi_parse_der_cert(const unsigned char *der,
|
||||
size_t der_len, char **err);
|
||||
|
||||
void *ngx_stream_lua_ffi_parse_pem_priv_key(const unsigned char *pem,
|
||||
size_t pem_len, char **err);
|
||||
|
||||
void *ngx_stream_lua_ffi_parse_der_priv_key(const unsigned char *der,
|
||||
size_t der_len, char **err);
|
||||
|
||||
int ngx_stream_lua_ffi_set_cert(void *r,
|
||||
void *cdata, char **err);
|
||||
|
||||
|
|
@ -63,6 +69,9 @@ ffi.cdef[[
|
|||
|
||||
int ngx_stream_lua_ffi_ssl_verify_client(void *r, void *cdata, int depth, char **err);
|
||||
|
||||
int ngx_stream_lua_ffi_ssl_client_random(ngx_stream_lua_request_t *r,
|
||||
unsigned char *out, size_t *outlen, char **err);
|
||||
|
||||
]]
|
||||
_EOC_
|
||||
}
|
||||
|
|
@ -990,3 +999,240 @@ lua ssl server name: "test.com"
|
|||
--- no_error_log
|
||||
[error]
|
||||
[alert]
|
||||
|
||||
|
||||
|
||||
=== TEST 10: DER cert + private key cdata
|
||||
--- stream_config
|
||||
server {
|
||||
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
|
||||
|
||||
ssl_certificate_by_lua_block {
|
||||
collectgarbage()
|
||||
|
||||
local ffi = require "ffi"
|
||||
require "defines"
|
||||
|
||||
local errmsg = ffi.new("char *[1]")
|
||||
|
||||
local r = require "resty.core.base" .get_request()
|
||||
if not r then
|
||||
ngx.log(ngx.ERR, "no request found")
|
||||
return
|
||||
end
|
||||
|
||||
ffi.C.ngx_stream_lua_ffi_ssl_clear_certs(r, errmsg)
|
||||
|
||||
local f = assert(io.open("t/cert/test_der.crt", "rb"))
|
||||
local cert_data = f:read("*all")
|
||||
f:close()
|
||||
|
||||
local cert = ffi.C.ngx_stream_lua_ffi_parse_der_cert(cert_data, #cert_data, errmsg)
|
||||
if not cert then
|
||||
ngx.log(ngx.ERR, "failed to parse DER cert: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
local rc = ffi.C.ngx_stream_lua_ffi_set_cert(r, cert, errmsg)
|
||||
if rc ~= 0 then
|
||||
ngx.log(ngx.ERR, "failed to set cdata cert: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
ffi.C.ngx_stream_lua_ffi_free_cert(cert)
|
||||
|
||||
f = assert(io.open("t/cert/test_der.key", "rb"))
|
||||
local pkey_data = f:read("*all")
|
||||
f:close()
|
||||
|
||||
local pkey = ffi.C.ngx_stream_lua_ffi_parse_der_priv_key(pkey_data, #pkey_data, errmsg)
|
||||
if pkey == nil then
|
||||
ngx.log(ngx.ERR, "failed to parse DER priv key: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
local rc = ffi.C.ngx_stream_lua_ffi_set_priv_key(r, pkey, errmsg)
|
||||
if rc ~= 0 then
|
||||
ngx.log(ngx.ERR, "failed to set cdata priv key: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
ffi.C.ngx_stream_lua_ffi_free_priv_key(pkey)
|
||||
}
|
||||
|
||||
ssl_certificate ../../cert/test2.crt;
|
||||
ssl_certificate_key ../../cert/test2.key;
|
||||
|
||||
return 'it works!\n';
|
||||
}
|
||||
--- stream_server_config
|
||||
lua_ssl_trusted_certificate ../../cert/test.crt;
|
||||
|
||||
content_by_lua_block {
|
||||
do
|
||||
local sock = ngx.socket.tcp()
|
||||
|
||||
sock:settimeout(2000)
|
||||
|
||||
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))
|
||||
|
||||
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 handshake: userdata
|
||||
received: it works!
|
||||
close: 1 nil
|
||||
|
||||
--- error_log
|
||||
lua ssl server name: "test.com"
|
||||
|
||||
--- no_error_log
|
||||
[error]
|
||||
[alert]
|
||||
|
||||
|
||||
|
||||
=== TEST 11: client random
|
||||
--- stream_config
|
||||
server {
|
||||
listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl;
|
||||
|
||||
ssl_certificate_by_lua_block {
|
||||
collectgarbage()
|
||||
|
||||
local ffi = require "ffi"
|
||||
require "defines"
|
||||
|
||||
local errmsg = ffi.new("char *[1]")
|
||||
|
||||
local r = require "resty.core.base" .get_request()
|
||||
if not r then
|
||||
ngx.log(ngx.ERR, "no request found")
|
||||
return
|
||||
end
|
||||
|
||||
-- test client random length
|
||||
local out = ffi.new("unsigned char[?]", 0)
|
||||
local sizep = ffi.new("size_t[1]", 0)
|
||||
|
||||
local rc = ffi.C.ngx_stream_lua_ffi_ssl_client_random(r, out, sizep, errmsg)
|
||||
if rc ~= 0 then
|
||||
ngx.log(ngx.ERR, "failed to get client random length: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
if tonumber(sizep[0]) ~= 32 then
|
||||
ngx.log(ngx.ERR, "client random length does not equal 32")
|
||||
return
|
||||
end
|
||||
|
||||
-- test client random value
|
||||
out = ffi.new("unsigned char[?]", 50)
|
||||
sizep = ffi.new("size_t[1]", 50)
|
||||
|
||||
rc = ffi.C.ngx_stream_lua_ffi_ssl_client_random(r, out, sizep, errmsg)
|
||||
if rc ~= 0 then
|
||||
ngx.log(ngx.ERR, "failed to get client random: ",
|
||||
ffi.string(errmsg[0]))
|
||||
return
|
||||
end
|
||||
|
||||
local init_v = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
if ffi.string(out, sizep[0]) == init_v then
|
||||
ngx.log(ngx.ERR, "maybe the client random value is incorrect")
|
||||
return
|
||||
end
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
content_by_lua_block {
|
||||
do
|
||||
local sock = ngx.socket.tcp()
|
||||
|
||||
sock:settimeout(2000)
|
||||
|
||||
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))
|
||||
|
||||
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 handshake: userdata
|
||||
received: it works!
|
||||
close: 1 nil
|
||||
|
||||
--- error_log
|
||||
lua ssl server name: "test.com"
|
||||
|
||||
--- no_error_log
|
||||
[error]
|
||||
[alert]
|
||||
|
|
|
|||
BIN
t/cert/test_der.crt
Normal file
BIN
t/cert/test_der.crt
Normal file
Binary file not shown.
BIN
t/cert/test_der.key
Normal file
BIN
t/cert/test_der.key
Normal file
Binary file not shown.
Loading…
Reference in a new issue