diff options
-rw-r--r-- | conf/modules.d/redis.conf | 1 | ||||
-rw-r--r-- | lualib/lua_redis.lua | 37 | ||||
-rw-r--r-- | lualib/rspamadm/configwizard.lua | 16 | ||||
-rw-r--r-- | lualib/rspamadm/fuzzy_convert.lua | 34 | ||||
-rw-r--r-- | src/libserver/fuzzy_backend/fuzzy_backend_redis.c | 26 | ||||
-rw-r--r-- | src/libserver/redis_pool.cxx | 53 | ||||
-rw-r--r-- | src/libserver/redis_pool.h | 3 | ||||
-rw-r--r-- | src/libstat/backends/redis_backend.c | 21 | ||||
-rw-r--r-- | src/libstat/learn_cache/redis_cache.c | 21 | ||||
-rw-r--r-- | src/lua/lua_redis.c | 17 | ||||
-rw-r--r-- | src/plugins/lua/bimi.lua | 9 | ||||
-rw-r--r-- | src/rspamadm/fuzzy_convert.c | 8 | ||||
-rw-r--r-- | src/rspamadm/stat_convert.c | 9 |
13 files changed, 212 insertions, 43 deletions
diff --git a/conf/modules.d/redis.conf b/conf/modules.d/redis.conf index eb430cbb1..24948b150 100644 --- a/conf/modules.d/redis.conf +++ b/conf/modules.d/redis.conf @@ -19,6 +19,7 @@ redis { #disabled_modules = ["ratelimit"]; # List of modules that should not use redis from this section #timeout = 1s; #db = "0"; + #username = "some_username"; #password = "some_password"; .include(try=true,priority=5) "${DBDIR}/dynamic/redis.conf" .include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/redis.conf" diff --git a/lualib/lua_redis.lua b/lualib/lua_redis.lua index b03160bb0..377541f87 100644 --- a/lualib/lua_redis.lua +++ b/lualib/lua_redis.lua @@ -30,12 +30,14 @@ local common_schema = { database = ts.string:is_optional():describe("Database number"), dbname = ts.string:is_optional():describe("Database number"), prefix = ts.string:is_optional():describe("Key prefix"), + username = ts.string:is_optional():describe("Username"), password = ts.string:is_optional():describe("Password"), expand_keys = ts.boolean:is_optional():describe("Expand keys"), sentinels = (ts.string + ts.array_of(ts.string)):is_optional():describe("Sentinel servers"), sentinel_watch_time = (ts.number + ts.string / lutil.parse_time_interval):is_optional():describe("Sentinel watch time"), sentinel_masters_pattern = ts.string:is_optional():describe("Sentinel masters pattern"), sentinel_master_maxerrors = (ts.number + ts.string / tonumber):is_optional():describe("Sentinel master max errors"), + sentinel_username = ts.string:is_optional():describe("sentinel username"), sentinel_password = ts.string:is_optional():describe("Sentinel password"), } @@ -153,6 +155,7 @@ local function redis_query_sentinel(ev_base, params, initialised) local ret = rspamd_redis.make_request { host = addr:get_addr(), timeout = params.timeout, + username = params.sentinel_username, password = params.sentinel_password, config = rspamd_config, ev_base = ev_base, @@ -184,6 +187,7 @@ local function redis_query_sentinel(ev_base, params, initialised) timeout = params.timeout, config = rspamd_config, ev_base = ev_base, + username = params.sentinel_username, password = params.sentinel_password, cmd = 'SENTINEL', args = { 'masters' }, @@ -366,6 +370,9 @@ local function process_redis_opts(options, redis_params) redis_params['db'] = tostring(options['database']) end end + if options['username'] and not redis_params['username'] then + redis_params['username'] = options['username'] + end if options['password'] and not redis_params['password'] then redis_params['password'] = options['password'] end @@ -996,6 +1003,10 @@ local function rspamd_redis_make_request(task, redis_params, key, is_write, end end + if redis_params['username'] then + options['username'] = redis_params['username'] + end + if redis_params['password'] then options['password'] = redis_params['password'] end @@ -1086,6 +1097,10 @@ local function redis_make_request_taskless(ev_base, cfg, redis_params, key, end end + if redis_params['username'] then + options['username'] = redis_params['username'] + end + if redis_params['password'] then options['password'] = redis_params['password'] end @@ -1157,6 +1172,10 @@ local function prepare_redis_call(script) upstream = s } + if script.redis_params['username'] then + cur_opts['username'] = script.redis_params['username'] + end + if script.redis_params['password'] then cur_opts['password'] = script.redis_params['password'] end @@ -1497,7 +1516,15 @@ local function redis_connect_sync(redis_params, is_write, key, cfg, ev_base) if conn then local need_exec = false - if redis_params['password'] then + if redis_params['username'] then + if redis_params['password'] then + conn:add_cmd('AUTH', { redis_params['username'], redis_params['password'] }) + need_exec = true + else + logger.errx('Redis requires a password when username is supplied') + return false, nil, addr + end + elseif redis_params['password'] then conn:add_cmd('AUTH', { redis_params['password'] }) need_exec = true end @@ -1602,6 +1629,10 @@ exports.request = function(redis_params, attrs, req) opts.args = req end + if redis_params.username then + opts.username = redis_params.username + end + if redis_params.password then opts.password = redis_params.password end @@ -1701,6 +1732,10 @@ exports.connect = function(redis_params, attrs) opts.host = addr:get_addr() opts.timeout = redis_params.timeout + if redis_params.username then + opts.username = redis_params.username + end + if redis_params.password then opts.password = redis_params.password end diff --git a/lualib/rspamadm/configwizard.lua b/lualib/rspamadm/configwizard.lua index 27c358e3b..7bcda5a01 100644 --- a/lualib/rspamadm/configwizard.lua +++ b/lualib/rspamadm/configwizard.lua @@ -249,7 +249,21 @@ local function setup_redis(cfg, changes) redis_params['write_servers'] = ws end - if ask_yes_no('Do you have any password set for your Redis?') then + if ask_yes_no('Do you have any username set for your Redis?') then + local usernm = readline_default("Enter Redis username:", nil) + + if usernm then + changes.l['redis.conf']['username'] = usernm + redis_params['username'] = usernm + end + + local passwd = readline_default("Enter Redis password:", nil) + + if passwd then + changes.l['redis.conf']['password'] = passwd + redis_params['password'] = passwd + end + elseif ask_yes_no('Do you have any password set for your Redis?') then local passwd = readline_default("Enter Redis password:", nil) if passwd then diff --git a/lualib/rspamadm/fuzzy_convert.lua b/lualib/rspamadm/fuzzy_convert.lua index a31baa4e2..67a2664bc 100644 --- a/lualib/rspamadm/fuzzy_convert.lua +++ b/lualib/rspamadm/fuzzy_convert.lua @@ -12,7 +12,16 @@ local function connect_redis(server, password, db) return nil, 'Cannot connect: ' .. err end - if password then + if username then + if password then + ret = conn:add_cmd('AUTH', { username, password }) + if not ret then + return nil, 'Cannot queue command' + end + else + return nil, 'Redis requires a password when username is supplied' + end + else if password then ret = conn:add_cmd('AUTH', { password }) if not ret then return nil, 'Cannot queue command' @@ -28,8 +37,8 @@ local function connect_redis(server, password, db) return conn, nil end -local function send_digests(digests, redis_host, redis_password, redis_db) - local conn, err = connect_redis(redis_host, redis_password, redis_db) +local function send_digests(digests, redis_host, redis_username, redis_password, redis_db) + local conn, err = connect_redis(redis_host, redis_username, redis_password, redis_db) if err then print(err) return false @@ -62,8 +71,8 @@ local function send_digests(digests, redis_host, redis_password, redis_db) return true end -local function send_shingles(shingles, redis_host, redis_password, redis_db) - local conn, err = connect_redis(redis_host, redis_password, redis_db) +local function send_shingles(shingles, redis_host, redis_username, redis_password, redis_db) + local conn, err = connect_redis(redis_host, redis_username, redis_password, redis_db) if err then print("Redis error: " .. err) return false @@ -95,8 +104,8 @@ local function send_shingles(shingles, redis_host, redis_password, redis_db) return true end -local function update_counters(total, redis_host, redis_password, redis_db) - local conn, err = connect_redis(redis_host, redis_password, redis_db) +local function update_counters(total, redis_host, redis_username, redis_password, redis_db) + local conn, err = connect_redis(redis_host, redis_username, redis_password, redis_db) if err then print(err) return false @@ -135,6 +144,7 @@ return function(_, res) local total_digests = 0 local total_shingles = 0 local lim_batch = 1000 -- Update each 1000 entries + local redis_username = res['redis_username'] local redis_password = res['redis_password'] local redis_db = nil @@ -162,14 +172,14 @@ return function(_, res) end end if num_batch_digests >= lim_batch then - if not send_digests(digests, res['redis_host'], redis_password, redis_db) then + if not send_digests(digests, res['redis_host'], redis_username, redis_password, redis_db) then return end num_batch_digests = 0 digests = {} end if num_batch_shingles >= lim_batch then - if not send_shingles(shingles, res['redis_host'], redis_password, redis_db) then + if not send_shingles(shingles, res['redis_host'], redis_username, redis_password, redis_db) then return end num_batch_shingles = 0 @@ -177,12 +187,12 @@ return function(_, res) end end if digests[1] then - if not send_digests(digests, res['redis_host'], redis_password, redis_db) then + if not send_digests(digests, res['redis_host'], redis_username, redis_password, redis_db) then return end end if shingles[1] then - if not send_shingles(shingles, res['redis_host'], redis_password, redis_db) then + if not send_shingles(shingles, res['redis_host'], redis_username, redis_password, redis_db) then return end end @@ -191,7 +201,7 @@ return function(_, res) 'Migrated %d digests and %d shingles', total_digests, total_shingles ) - if not update_counters(total_digests, res['redis_host'], redis_password, redis_db) then + if not update_counters(total_digests, res['redis_host'], redis_username, redis_password, redis_db) then message = message .. ' but failed to update counters' end print(message) diff --git a/src/libserver/fuzzy_backend/fuzzy_backend_redis.c b/src/libserver/fuzzy_backend/fuzzy_backend_redis.c index 9b5b3bc02..7ab7ca63e 100644 --- a/src/libserver/fuzzy_backend/fuzzy_backend_redis.c +++ b/src/libserver/fuzzy_backend/fuzzy_backend_redis.c @@ -52,6 +52,7 @@ INIT_LOG_MODULE(fuzzy_redis) struct rspamd_fuzzy_backend_redis { lua_State *L; const gchar *redis_object; + const gchar *username; const gchar *password; const gchar *dbname; gchar *id; @@ -256,6 +257,14 @@ rspamd_fuzzy_backend_init_redis(struct rspamd_fuzzy_backend *bk, } lua_pop(L, 1); + lua_pushstring(L, "username"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + backend->username = rspamd_mempool_strdup(cfg->cfg_pool, + lua_tostring(L, -1)); + } + lua_pop(L, 1); + lua_pushstring(L, "password"); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING) { @@ -277,6 +286,11 @@ rspamd_fuzzy_backend_init_redis(struct rspamd_fuzzy_backend *bk, strlen(backend->dbname)); } + if (backend->username) { + rspamd_cryptobox_hash_update(&st, backend->username, + strlen(backend->username)); + } + if (backend->password) { rspamd_cryptobox_hash_update(&st, backend->password, strlen(backend->password)); @@ -681,7 +695,8 @@ void rspamd_fuzzy_backend_check_redis(struct rspamd_fuzzy_backend *bk, addr = rspamd_upstream_addr_next(up); g_assert(addr != NULL); session->ctx = rspamd_redis_pool_connect(backend->pool, - backend->dbname, backend->password, + backend->dbname, + backend->username, backend->password, rspamd_inet_address_to_string(addr), rspamd_inet_address_get_port(addr)); @@ -819,7 +834,8 @@ void rspamd_fuzzy_backend_count_redis(struct rspamd_fuzzy_backend *bk, addr = rspamd_upstream_addr_next(up); g_assert(addr != NULL); session->ctx = rspamd_redis_pool_connect(backend->pool, - backend->dbname, backend->password, + backend->dbname, + backend->username, backend->password, rspamd_inet_address_to_string(addr), rspamd_inet_address_get_port(addr)); @@ -956,7 +972,8 @@ void rspamd_fuzzy_backend_version_redis(struct rspamd_fuzzy_backend *bk, addr = rspamd_upstream_addr_next(up); g_assert(addr != NULL); session->ctx = rspamd_redis_pool_connect(backend->pool, - backend->dbname, backend->password, + backend->dbname, + backend->username, backend->password, rspamd_inet_address_to_string(addr), rspamd_inet_address_get_port(addr)); @@ -1527,7 +1544,8 @@ void rspamd_fuzzy_backend_update_redis(struct rspamd_fuzzy_backend *bk, addr = rspamd_upstream_addr_next(up); g_assert(addr != NULL); session->ctx = rspamd_redis_pool_connect(backend->pool, - backend->dbname, backend->password, + backend->dbname, + backend->username, backend->password, rspamd_inet_address_to_string(addr), rspamd_inet_address_get_port(addr)); diff --git a/src/libserver/redis_pool.cxx b/src/libserver/redis_pool.cxx index 86ff2adb2..34c09d055 100644 --- a/src/libserver/redis_pool.cxx +++ b/src/libserver/redis_pool.cxx @@ -62,6 +62,7 @@ struct redis_pool_connection { explicit redis_pool_connection(redis_pool *_pool, redis_pool_elt *_elt, const std::string &db, + const std::string &username, const std::string &password, struct redisAsyncContext *_ctx); @@ -87,6 +88,7 @@ class redis_pool_elt { std::list<redis_pool_connection_ptr> terminating; std::string ip; std::string db; + std::string username; std::string password; int port; redis_pool_key_t key; @@ -100,16 +102,20 @@ public: redis_pool_elt(redis_pool_elt &&other) = default; explicit redis_pool_elt(redis_pool *_pool, - const gchar *_db, const gchar *_password, + const gchar *_db, const gchar *_username, + const gchar *_password, const char *_ip, int _port) : pool(_pool), ip(_ip), port(_port), - key(redis_pool_elt::make_key(_db, _password, _ip, _port)) + key(redis_pool_elt::make_key(_db, _username, _password, _ip, _port)) { is_unix = ip[0] == '.' || ip[0] == '/'; if (_db) { db = _db; } + if( _username ) { + username = _username; + } if (_password) { password = _password; } @@ -144,8 +150,8 @@ public: conn->elt_pos = std::prev(std::end(terminating)); } - inline static auto make_key(const gchar *db, const gchar *password, - const char *ip, int port) -> redis_pool_key_t + inline static auto make_key(const gchar *db, const gchar *username, + const gchar *password, const char *ip, int port) -> redis_pool_key_t { rspamd_cryptobox_fast_hash_state_t st; @@ -154,6 +160,9 @@ public: if (db) { rspamd_cryptobox_fast_hash_update(&st, db, strlen(db)); } + if (username) { + rspamd_cryptobox_fast_hash_update(&st, username, strlen(username)); + } if (password) { rspamd_cryptobox_fast_hash_update(&st, password, strlen(password)); } @@ -232,8 +241,8 @@ public: cfg = _cfg; } - auto new_connection(const gchar *db, const gchar *password, - const char *ip, int port) -> redisAsyncContext *; + auto new_connection(const gchar *db, const gchar *username, + const gchar *password, const char *ip, int port) -> redisAsyncContext *; auto release_connection(redisAsyncContext *ctx, enum rspamd_redis_pool_release_type how) -> void; @@ -398,6 +407,7 @@ auto redis_pool_connection::schedule_timeout() -> void redis_pool_connection::redis_pool_connection(redis_pool *_pool, redis_pool_elt *_elt, const std::string &db, + const std::string &username, const std::string &password, struct redisAsyncContext *_ctx) : ctx(_ctx), elt(_elt), pool(_pool) @@ -413,7 +423,18 @@ redis_pool_connection::redis_pool_connection(redis_pool *_pool, redisLibevAttach(pool->event_loop, ctx); redisAsyncSetDisconnectCallback(ctx, redis_pool_connection::redis_on_disconnect); - if (!password.empty()) { + if (!username.empty()) { + if (!password.empty()) { + redisAsyncCommand(ctx, nullptr, nullptr, + "AUTH %s %s", username.c_str(), password.c_str()); + } + else { + msg_err("Redis requires a password when username is supplied"); + redisAsyncFree(ctx); + return nullptr; + } + } + else if (!password.empty()) { redisAsyncCommand(ctx, nullptr, nullptr, "AUTH %s", password.c_str()); } @@ -464,7 +485,7 @@ auto redis_pool_elt::new_connection() -> redisAsyncContext * auto *nctx = redis_async_new(); if (nctx) { active.emplace_front(std::make_unique<redis_pool_connection>(pool, this, - db.c_str(), password.c_str(), nctx)); + db.c_str(), username.c_str(), password.c_str(), nctx)); active.front()->elt_pos = active.begin(); } @@ -475,7 +496,7 @@ auto redis_pool_elt::new_connection() -> redisAsyncContext * auto *nctx = redis_async_new(); if (nctx) { active.emplace_front(std::make_unique<redis_pool_connection>(pool, this, - db.c_str(), password.c_str(), nctx)); + db.c_str(), username.c_str(), password.c_str(), nctx)); active.front()->elt_pos = active.begin(); } @@ -485,12 +506,12 @@ auto redis_pool_elt::new_connection() -> redisAsyncContext * RSPAMD_UNREACHABLE; } -auto redis_pool::new_connection(const gchar *db, const gchar *password, - const char *ip, int port) -> redisAsyncContext * +auto redis_pool::new_connection(const gchar *db, const gchar *username, + const gchar *password, const char *ip, int port) -> redisAsyncContext * { if (!wanna_die) { - auto key = redis_pool_elt::make_key(db, password, ip, port); + auto key = redis_pool_elt::make_key(db, username, password, ip, port); auto found_elt = elts_by_key.find(key); if (found_elt != elts_by_key.end()) { @@ -501,7 +522,7 @@ auto redis_pool::new_connection(const gchar *db, const gchar *password, else { /* Need to create a pool */ auto nelt = elts_by_key.try_emplace(key, - this, db, password, ip, port); + this, db, username, password, ip, port); return nelt.first->second.new_connection(); } @@ -583,13 +604,13 @@ void rspamd_redis_pool_config(void *p, struct redisAsyncContext * rspamd_redis_pool_connect(void *p, - const gchar *db, const gchar *password, - const char *ip, int port) + const gchar *db, const gchar *username, + const gchar *password, const char *ip, int port) { g_assert(p != NULL); auto *pool = reinterpret_cast<class rspamd::redis_pool *>(p); - return pool->new_connection(db, password, ip, port); + return pool->new_connection(db, username, password, ip, port); } diff --git a/src/libserver/redis_pool.h b/src/libserver/redis_pool.h index 339bf5f53..ecdaa0f85 100644 --- a/src/libserver/redis_pool.h +++ b/src/libserver/redis_pool.h @@ -45,6 +45,7 @@ void rspamd_redis_pool_config(void *pool, * Create or reuse the specific redis connection * @param pool * @param db + * @param username * @param password * @param ip * @param port @@ -52,7 +53,7 @@ void rspamd_redis_pool_config(void *pool, */ struct redisAsyncContext *rspamd_redis_pool_connect( void *pool, - const gchar *db, const gchar *password, + const gchar *db, const gchar *username, const gchar *password, const char *ip, int port); enum rspamd_redis_pool_release_type { diff --git a/src/libstat/backends/redis_backend.c b/src/libstat/backends/redis_backend.c index a0d11bb0d..72ffd6c44 100644 --- a/src/libstat/backends/redis_backend.c +++ b/src/libstat/backends/redis_backend.c @@ -45,6 +45,7 @@ struct redis_stat_ctx { gint conf_ref; struct rspamd_stat_async_elt *stat_elt; const gchar *redis_object; + const gchar *username; const gchar *password; const gchar *dbname; gdouble timeout; @@ -363,7 +364,17 @@ gsize rspamd_redis_expand_object(const gchar *pattern, static void rspamd_redis_maybe_auth(struct redis_stat_ctx *ctx, redisAsyncContext *redis) { - if (ctx->password) { + if (ctx->username) { + if (ctx->password) { + redisAsyncCommand(redis, NULL, NULL, "AUTH %s %s", ctx->username, ctx->password); + } + else { + msg_err("Redis requires a password when username is supplied"); + redisAsyncFree(ctx); + return NULL; + } + } + else if (ctx->password) { redisAsyncCommand(redis, NULL, NULL, "AUTH %s", ctx->password); } if (ctx->dbname) { @@ -1603,6 +1614,14 @@ rspamd_redis_init(struct rspamd_stat_ctx *ctx, } lua_pop(L, 1); + lua_pushstring(L, "username"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + backend->username = rspamd_mempool_strdup(cfg->cfg_pool, + lua_tostring(L, -1)); + } + lua_pop(L, 1); + lua_pushstring(L, "password"); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING) { diff --git a/src/libstat/learn_cache/redis_cache.c b/src/libstat/learn_cache/redis_cache.c index 3026009bc..0bbae8560 100644 --- a/src/libstat/learn_cache/redis_cache.c +++ b/src/libstat/learn_cache/redis_cache.c @@ -35,6 +35,7 @@ static const gchar *M = "redis learn cache"; struct rspamd_redis_cache_ctx { lua_State *L; struct rspamd_statfile_config *stcf; + const gchar *username; const gchar *password; const gchar *dbname; const gchar *redis_object; @@ -77,7 +78,17 @@ static void rspamd_redis_cache_maybe_auth(struct rspamd_redis_cache_ctx *ctx, redisAsyncContext *redis) { - if (ctx->password) { + if (ctx->username) { + if (ctx->password) { + redisAsyncCommand(redis, NULL, NULL, "AUTH %s %s", ctx->username, ctx->password); + } + else { + msg_err("Redis requires a password when username is supplied"); + redisAsyncFree(ctx); + return NULL; + } + } + else if (ctx->password) { redisAsyncCommand(redis, NULL, NULL, "AUTH %s", ctx->password); } if (ctx->dbname) { @@ -328,6 +339,14 @@ rspamd_stat_cache_redis_init(struct rspamd_stat_ctx *ctx, } lua_pop(L, 1); + lua_pushstring(L, "username"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + cache_ctx->username = rspamd_mempool_strdup(cfg->cfg_pool, + lua_tostring(L, -1)); + } + lua_pop(L, 1); + lua_pushstring(L, "password"); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING) { diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index 2ac5a47b7..1ad3b3d17 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -110,9 +110,9 @@ struct lua_redis_userdata { }; #define msg_debug_lua_redis(...) rspamd_conditional_debug_fast(NULL, NULL, \ - rspamd_lua_redis_log_id, "lua_redis", ud->log_tag, \ - G_STRFUNC, \ - __VA_ARGS__) + rspamd_lua_redis_log_id, "lua_redis", ud->log_tag, \ + G_STRFUNC, \ + __VA_ARGS__) INIT_LOG_MODULE(lua_redis) #define LUA_REDIS_SPECIFIC_REPLIED (1 << 0) @@ -875,7 +875,7 @@ rspamd_lua_redis_prepare_connection(lua_State *L, gint *pcbref, gboolean is_asyn struct rspamd_lua_ip *addr = NULL; struct rspamd_task *task = NULL; const gchar *host = NULL; - const gchar *password = NULL, *dbname = NULL, *log_tag = NULL; + const gchar *username = NULL, *password = NULL, *dbname = NULL, *log_tag = NULL; gint cbref = -1; struct rspamd_config *cfg = NULL; struct rspamd_async_session *session = NULL; @@ -970,6 +970,13 @@ rspamd_lua_redis_prepare_connection(lua_State *L, gint *pcbref, gboolean is_asyn } lua_pop(L, 1); + lua_pushstring(L, "username"); + lua_gettable(L, -2); + if (lua_type(L, -1) == LUA_TSTRING) { + username = lua_tostring(L, -1); + } + lua_pop(L, 1); + lua_pushstring(L, "password"); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING) { @@ -1053,7 +1060,7 @@ rspamd_lua_redis_prepare_connection(lua_State *L, gint *pcbref, gboolean is_asyn if (ret) { ud->terminated = 0; ud->ctx = rspamd_redis_pool_connect(ud->pool, - dbname, password, + dbname, username, password, rspamd_inet_address_to_string(addr->addr), rspamd_inet_address_get_port(addr->addr)); diff --git a/src/plugins/lua/bimi.lua b/src/plugins/lua/bimi.lua index 914484543..5053cc941 100644 --- a/src/plugins/lua/bimi.lua +++ b/src/plugins/lua/bimi.lua @@ -263,7 +263,14 @@ local function check_bimi_vmc(task, domain, record) if redis_params.db then db = string.format('/%s', redis_params.db) end - if redis_params.password then + if redis_params.username then + if redis_params.password then + password = string.format( '%s:%s@', redis_params.username, redis_params.password) + else + rspamd_logger.errx(task, "Redis requires a password when username is supplied") + return + end + elseif redis_params.password then password = string.format(':%s@', redis_params.password) end local redis_server = string.format('redis://%s%s:%s%s', diff --git a/src/rspamadm/fuzzy_convert.c b/src/rspamadm/fuzzy_convert.c index 1b2866b59..5d967a64c 100644 --- a/src/rspamadm/fuzzy_convert.c +++ b/src/rspamadm/fuzzy_convert.c @@ -21,6 +21,7 @@ static gchar *source_db = NULL; static gchar *redis_host = NULL; static gchar *redis_db = NULL; +static gchar *redis_username = NULL; static gchar *redis_password = NULL; static int64_t fuzzy_expiry = 0; @@ -46,6 +47,8 @@ static GOptionEntry entries[] = { "Output redis ip (in format ip:port)", NULL}, {"dbname", 'D', 0, G_OPTION_ARG_STRING, &redis_db, "Database in redis (should be numeric)", NULL}, + {"username", 'u', 0, G_OPTION_ARG_STRING, &redis_username, + "Username to connect to redis", NULL}, {"password", 'p', 0, G_OPTION_ARG_STRING, &redis_password, "Password to connect to redis", NULL}, {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}}; @@ -63,6 +66,7 @@ rspamadm_fuzzyconvert_help(gboolean full_help, const struct rspamadm_command *cm "-d: input sqlite\n" "-h: output redis ip (in format ip:port)\n" "-D: output redis database\n" + "-u: redis username\n"; "-p: redis password\n"; } else { @@ -117,6 +121,10 @@ rspamadm_fuzzyconvert(gint argc, gchar **argv, const struct rspamadm_command *cm ucl_object_insert_key(obj, ucl_object_fromint(fuzzy_expiry), "expiry", 0, false); + if (redis_username) { + ucl_object_insert_key(obj, ucl_object_fromstring(redis_username), + "redis_username", 0, false); + } if (redis_password) { ucl_object_insert_key(obj, ucl_object_fromstring(redis_password), "redis_password", 0, false); diff --git a/src/rspamadm/stat_convert.c b/src/rspamadm/stat_convert.c index ba2c4efb9..0741279aa 100644 --- a/src/rspamadm/stat_convert.c +++ b/src/rspamadm/stat_convert.c @@ -34,6 +34,7 @@ static gchar *cache_db = NULL; /* Outputs */ static gchar *redis_host = NULL; static gchar *redis_db = NULL; +static gchar *redis_username = NULL; static gchar *redis_password = NULL; static gboolean reset_previous = FALSE; @@ -70,6 +71,8 @@ static GOptionEntry entries[] = { "Input learn cache", NULL}, {"redis-host", 'h', 0, G_OPTION_ARG_STRING, &redis_host, "Output redis ip (in format ip:port)", NULL}, + {"redis-username", 'u', 0, G_OPTION_ARG_STRING, &redis_username, + "Username to connect to redis", NULL}, {"redis-password", 'p', 0, G_OPTION_ARG_STRING, &redis_password, "Password to connect to redis", NULL}, {"redis-db", 'd', 0, G_OPTION_ARG_STRING, &redis_db, @@ -92,6 +95,7 @@ rspamadm_statconvert_help(gboolean full_help, const struct rspamadm_command *cmd "** Or specify options directly **\n" "--redis-host: output redis ip (in format ip:port)\n" "--redis-db: output redis database\n" + "--redis-username: redis username\n" "--redis-password: redis password\n" "--cache: sqlite3 file for learn cache\n" "--spam-db: sqlite3 input file for spam data\n" @@ -229,6 +233,11 @@ rspamadm_statconvert(gint argc, gchar **argv, const struct rspamadm_command *cmd "dbname", 0, false); } + if (redis_username) { + ucl_object_insert_key(redis, ucl_object_fromstring(redis_username), + "username", 0, false); + } + if (redis_password) { ucl_object_insert_key(redis, ucl_object_fromstring(redis_password), "password", 0, false); |