diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d89339e..f068f76 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,9 +12,14 @@ jobs: matrix: tarantool: ['1.10', '2.10', '2.11', '3.1', '3.2'] coveralls: [false] + static-build: [false] include: - - tarantool: '2.11' + - tarantool: '3.5' coveralls: true + static-build: false + - tarantool: '3.5' + coveralls: false + static-build: true runs-on: [ubuntu-22.04] steps: - uses: actions/checkout@master @@ -32,7 +37,8 @@ jobs: env: DEBIAN_FRONTEND: noninteractive - - name: Install Tarantool + - name: Install dynamic Tarantool + if: matrix.static-build == false run: tt install tarantool ${{ matrix.tarantool }} --dynamic - name: Cache rocks diff --git a/CHANGELOG.md b/CHANGELOG.md index 2043715..537634d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed -## [1.9.0] - 2025-11-11 +## [1.9.0] - 2025-11-12 The release introduces a new `ssl_verify_client` option and changes default behavior with provided `ca_file` param. Also a few bugs were fixed. diff --git a/http/server.lua b/http/server.lua index fa24e46..68757e6 100644 --- a/http/server.lua +++ b/http/server.lua @@ -1296,12 +1296,6 @@ local function url_for_httpd(httpd, name, args, query) end end -local VERIFY_CLIENT_OPTS = { - off = sslsocket.SET_VERIFY_FLAGS.SSL_VERIFY_NONE, - optional = sslsocket.SET_VERIFY_FLAGS.SSL_VERIFY_PEER, - on = bit.bor(sslsocket.SET_VERIFY_FLAGS.SSL_VERIFY_PEER, sslsocket.SET_VERIFY_FLAGS.SSL_VERIFY_FAIL_IF_NO_PEER), -} - local function create_ssl_ctx(host, port, opts) local ok, ctx = pcall(sslsocket.ctx, sslsocket.tls_server_method()) if ok ~= true then @@ -1334,11 +1328,7 @@ local function create_ssl_ctx(host, port, opts) ) end - local set_verify_flag = ( - opts.ssl_verify_client and VERIFY_CLIENT_OPTS[opts.ssl_verify_client] or - VERIFY_CLIENT_OPTS.off - ) - sslsocket.ctx_set_verify(ctx, set_verify_flag) + sslsocket.ctx_set_verify(ctx, opts.ssl_verify_client) end if opts.ssl_ciphers ~= nil then @@ -1380,6 +1370,12 @@ local function httpd_start(self) return self end +local AVAILABLE_SSL_VERIFY_CLIENT_OPTS = { + off = true, + optional = true, + on = true, +} + -- validate_ssl_opts validates ssl_opts and returns true if at least ssl_cert_file -- and ssl_key_file parameters are not nil. local function validate_ssl_opts(opts) @@ -1394,7 +1390,7 @@ local function validate_ssl_opts(opts) end if key == 'ssl_verify_client' then - if VERIFY_CLIENT_OPTS[value] == nil then + if AVAILABLE_SSL_VERIFY_CLIENT_OPTS[value] == nil then errorf('%q option not exists. Available options: "on", "off", "optional"', value) end end diff --git a/http/sslsocket.lua b/http/sslsocket.lua index 345d6ea..eea3226 100644 --- a/http/sslsocket.lua +++ b/http/sslsocket.lua @@ -62,6 +62,12 @@ local SET_VERIFY_FLAGS = { SSL_VERIFY_FAIL_IF_NO_PEER = 0x02, } +local VERIFY_CLIENT_OPTS = { + off = SET_VERIFY_FLAGS.SSL_VERIFY_NONE, + optional = SET_VERIFY_FLAGS.SSL_VERIFY_PEER, + on = bit.bor(SET_VERIFY_FLAGS.SSL_VERIFY_PEER, SET_VERIFY_FLAGS.SSL_VERIFY_FAIL_IF_NO_PEER), +} + local function slice_wait(timeout, starttime) if timeout == nil then return nil @@ -168,8 +174,9 @@ local function ctx_set_cipher_list(ctx, str) return true end -local function ctx_set_verify(ctx, flags) - ffi.C.SSL_CTX_set_verify(ctx, flags, box.NULL) +local function ctx_set_verify(ctx, mode) + mode = mode or 'off' + ffi.C.SSL_CTX_set_verify(ctx, VERIFY_CLIENT_OPTS[mode], box.NULL) end local default_ctx = ctx(ffi.C.TLS_server_method()) @@ -458,8 +465,6 @@ local function tcp_server(host, port, handler, timeout, sslctx) end return { - SET_VERIFY_FLAGS = SET_VERIFY_FLAGS, - tls_server_method = tls_server_method, ctx = ctx, diff --git a/test/helpers.lua b/test/helpers.lua index bfc6425..4991c4b 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -148,4 +148,17 @@ helpers.tcp_connection_exists = function(host, port) return ok end +local ffi = require('ffi') +local has_tls_method = pcall(function() + return ffi.C.TLS_server_method() ~= nil +end) + +helpers.skip_if_ssl_not_enabled = function() + luatest.skip_if(not has_tls_method, 'tarantool does not support ssl') +end + +helpers.skip_if_ssl_enabled = function() + luatest.skip_if(has_tls_method, 'tarantool supports ssl') +end + return helpers diff --git a/test/integration/http_tls_enabled_test.lua b/test/integration/http_tls_enabled_test.lua index 478ae5e..9b8259f 100644 --- a/test/integration/http_tls_enabled_test.lua +++ b/test/integration/http_tls_enabled_test.lua @@ -9,6 +9,10 @@ local g = t.group('ssl') local ssl_data_dir = fio.pathjoin(helpers.get_testdir_path(), "ssl_data") +g.before_all(function() + helpers.skip_if_ssl_not_enabled() +end) + local server_test_cases = { test_key_password_missing = { ssl_opts = { diff --git a/test/integration/http_tls_enabled_validate_test.lua b/test/integration/http_tls_enabled_validate_test.lua index ea4835f..3ac649b 100644 --- a/test/integration/http_tls_enabled_validate_test.lua +++ b/test/integration/http_tls_enabled_validate_test.lua @@ -111,10 +111,22 @@ local test_cases = { }, expected_err_msg = '"unknown" option not exists. Available options: "on", "off", "optional"' }, + ssl_socket_not_supported = { + check_ssl = true, + opts = { + ssl_cert_file = fio.pathjoin(ssl_data_dir, 'server.crt'), + ssl_key_file = fio.pathjoin(ssl_data_dir, 'server.key'), + }, + expected_err_msg = 'ssl socket is not supported', + } } for name, case in pairs(test_cases) do g['test_ssl_option_' .. name] = function() + helpers.skip_if_ssl_not_enabled() + if case.check_ssl == true then + helpers.skip_if_ssl_enabled() + end t.assert_error_msg_contains(case.expected_err_msg, function() http_server.new('host', 8080, case.opts) end) diff --git a/test/integration/httpd_role_test.lua b/test/integration/httpd_role_test.lua index cb5c43e..36dc92b 100644 --- a/test/integration/httpd_role_test.lua +++ b/test/integration/httpd_role_test.lua @@ -88,6 +88,10 @@ tls_config.groups['group-001'].replicasets['replicaset-001'].roles_cfg['roles.ht tls_config.groups['group-001'].replicasets['replicaset-001'].roles_cfg['roles.httpd'].default .ssl_password_file = fio.pathjoin(ssl_data_dir, 'passwords') +g.before_all(function() + helpers.skip_if_ssl_not_enabled() +end) + g.before_each(function(cg) helpers.skip_if_not_tarantool3() diff --git a/test/unit/httpd_role_test.lua b/test/unit/httpd_role_test.lua index 1321ea6..d554660 100644 --- a/test/unit/httpd_role_test.lua +++ b/test/unit/httpd_role_test.lua @@ -254,6 +254,9 @@ for name, case in pairs(validation_cases) do ) g[test_name] = function() + if name:find('ssl_') ~= nil and case.err == nil then + helpers.skip_if_ssl_not_enabled() + end local ok, res = pcall(httpd_role.validate, case.cfg) if case.err ~= nil then