Ver código fonte

Added support for Redis 6 ACL (username/password)

tags/3.7.1
laodc 10 meses atrás
pai
commit
75fdc829ba

+ 1
- 0
conf/modules.d/redis.conf Ver arquivo

#disabled_modules = ["ratelimit"]; # List of modules that should not use redis from this section #disabled_modules = ["ratelimit"]; # List of modules that should not use redis from this section
#timeout = 1s; #timeout = 1s;
#db = "0"; #db = "0";
#username = "some_username";
#password = "some_password"; #password = "some_password";
.include(try=true,priority=5) "${DBDIR}/dynamic/redis.conf" .include(try=true,priority=5) "${DBDIR}/dynamic/redis.conf"
.include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/redis.conf" .include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/redis.conf"

+ 36
- 1
lualib/lua_redis.lua Ver arquivo

database = ts.string:is_optional():describe("Database number"), database = ts.string:is_optional():describe("Database number"),
dbname = ts.string:is_optional():describe("Database number"), dbname = ts.string:is_optional():describe("Database number"),
prefix = ts.string:is_optional():describe("Key prefix"), prefix = ts.string:is_optional():describe("Key prefix"),
username = ts.string:is_optional():describe("Username"),
password = ts.string:is_optional():describe("Password"), password = ts.string:is_optional():describe("Password"),
expand_keys = ts.boolean:is_optional():describe("Expand keys"), expand_keys = ts.boolean:is_optional():describe("Expand keys"),
sentinels = (ts.string + ts.array_of(ts.string)):is_optional():describe("Sentinel servers"), 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_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_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_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"), sentinel_password = ts.string:is_optional():describe("Sentinel password"),
} }


local ret = rspamd_redis.make_request { local ret = rspamd_redis.make_request {
host = addr:get_addr(), host = addr:get_addr(),
timeout = params.timeout, timeout = params.timeout,
username = params.sentinel_username,
password = params.sentinel_password, password = params.sentinel_password,
config = rspamd_config, config = rspamd_config,
ev_base = ev_base, ev_base = ev_base,
timeout = params.timeout, timeout = params.timeout,
config = rspamd_config, config = rspamd_config,
ev_base = ev_base, ev_base = ev_base,
username = params.sentinel_username,
password = params.sentinel_password, password = params.sentinel_password,
cmd = 'SENTINEL', cmd = 'SENTINEL',
args = { 'masters' }, args = { 'masters' },
redis_params['db'] = tostring(options['database']) redis_params['db'] = tostring(options['database'])
end end
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 if options['password'] and not redis_params['password'] then
redis_params['password'] = options['password'] redis_params['password'] = options['password']
end end
end end
end end


if redis_params['username'] then
options['username'] = redis_params['username']
end

if redis_params['password'] then if redis_params['password'] then
options['password'] = redis_params['password'] options['password'] = redis_params['password']
end end
end end
end end


if redis_params['username'] then
options['username'] = redis_params['username']
end

if redis_params['password'] then if redis_params['password'] then
options['password'] = redis_params['password'] options['password'] = redis_params['password']
end end
upstream = s upstream = s
} }


if script.redis_params['username'] then
cur_opts['username'] = script.redis_params['username']
end

if script.redis_params['password'] then if script.redis_params['password'] then
cur_opts['password'] = script.redis_params['password'] cur_opts['password'] = script.redis_params['password']
end end


if conn then if conn then
local need_exec = false 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'] }) conn:add_cmd('AUTH', { redis_params['password'] })
need_exec = true need_exec = true
end end
opts.args = req opts.args = req
end end


if redis_params.username then
opts.username = redis_params.username
end

if redis_params.password then if redis_params.password then
opts.password = redis_params.password opts.password = redis_params.password
end end
opts.host = addr:get_addr() opts.host = addr:get_addr()
opts.timeout = redis_params.timeout opts.timeout = redis_params.timeout


if redis_params.username then
opts.username = redis_params.username
end

if redis_params.password then if redis_params.password then
opts.password = redis_params.password opts.password = redis_params.password
end end

+ 15
- 1
lualib/rspamadm/configwizard.lua Ver arquivo

redis_params['write_servers'] = ws redis_params['write_servers'] = ws
end 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) local passwd = readline_default("Enter Redis password:", nil)


if passwd then if passwd then

+ 22
- 12
lualib/rspamadm/fuzzy_convert.lua Ver arquivo

return nil, 'Cannot connect: ' .. err return nil, 'Cannot connect: ' .. err
end 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 }) ret = conn:add_cmd('AUTH', { password })
if not ret then if not ret then
return nil, 'Cannot queue command' return nil, 'Cannot queue command'
return conn, nil return conn, nil
end 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 if err then
print(err) print(err)
return false return false
return true return true
end 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 if err then
print("Redis error: " .. err) print("Redis error: " .. err)
return false return false
return true return true
end 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 if err then
print(err) print(err)
return false return false
local total_digests = 0 local total_digests = 0
local total_shingles = 0 local total_shingles = 0
local lim_batch = 1000 -- Update each 1000 entries local lim_batch = 1000 -- Update each 1000 entries
local redis_username = res['redis_username']
local redis_password = res['redis_password'] local redis_password = res['redis_password']
local redis_db = nil local redis_db = nil


end end
end end
if num_batch_digests >= lim_batch then 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 return
end end
num_batch_digests = 0 num_batch_digests = 0
digests = {} digests = {}
end end
if num_batch_shingles >= lim_batch then 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 return
end end
num_batch_shingles = 0 num_batch_shingles = 0
end end
end end
if digests[1] then 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 return
end end
end end
if shingles[1] then 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 return
end end
end end
'Migrated %d digests and %d shingles', 'Migrated %d digests and %d shingles',
total_digests, total_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' message = message .. ' but failed to update counters'
end end
print(message) print(message)

+ 22
- 4
src/libserver/fuzzy_backend/fuzzy_backend_redis.c Ver arquivo

struct rspamd_fuzzy_backend_redis { struct rspamd_fuzzy_backend_redis {
lua_State *L; lua_State *L;
const gchar *redis_object; const gchar *redis_object;
const gchar *username;
const gchar *password; const gchar *password;
const gchar *dbname; const gchar *dbname;
gchar *id; gchar *id;
} }
lua_pop(L, 1); 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_pushstring(L, "password");
lua_gettable(L, -2); lua_gettable(L, -2);
if (lua_type(L, -1) == LUA_TSTRING) { if (lua_type(L, -1) == LUA_TSTRING) {
strlen(backend->dbname)); strlen(backend->dbname));
} }


if (backend->username) {
rspamd_cryptobox_hash_update(&st, backend->username,
strlen(backend->username));
}

if (backend->password) { if (backend->password) {
rspamd_cryptobox_hash_update(&st, backend->password, rspamd_cryptobox_hash_update(&st, backend->password,
strlen(backend->password)); strlen(backend->password));
addr = rspamd_upstream_addr_next(up); addr = rspamd_upstream_addr_next(up);
g_assert(addr != NULL); g_assert(addr != NULL);
session->ctx = rspamd_redis_pool_connect(backend->pool, 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_to_string(addr),
rspamd_inet_address_get_port(addr)); rspamd_inet_address_get_port(addr));


addr = rspamd_upstream_addr_next(up); addr = rspamd_upstream_addr_next(up);
g_assert(addr != NULL); g_assert(addr != NULL);
session->ctx = rspamd_redis_pool_connect(backend->pool, 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_to_string(addr),
rspamd_inet_address_get_port(addr)); rspamd_inet_address_get_port(addr));


addr = rspamd_upstream_addr_next(up); addr = rspamd_upstream_addr_next(up);
g_assert(addr != NULL); g_assert(addr != NULL);
session->ctx = rspamd_redis_pool_connect(backend->pool, 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_to_string(addr),
rspamd_inet_address_get_port(addr)); rspamd_inet_address_get_port(addr));


addr = rspamd_upstream_addr_next(up); addr = rspamd_upstream_addr_next(up);
g_assert(addr != NULL); g_assert(addr != NULL);
session->ctx = rspamd_redis_pool_connect(backend->pool, 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_to_string(addr),
rspamd_inet_address_get_port(addr)); rspamd_inet_address_get_port(addr));



+ 37
- 16
src/libserver/redis_pool.cxx Ver arquivo

explicit redis_pool_connection(redis_pool *_pool, explicit redis_pool_connection(redis_pool *_pool,
redis_pool_elt *_elt, redis_pool_elt *_elt,
const std::string &db, const std::string &db,
const std::string &username,
const std::string &password, const std::string &password,
struct redisAsyncContext *_ctx); struct redisAsyncContext *_ctx);


std::list<redis_pool_connection_ptr> terminating; std::list<redis_pool_connection_ptr> terminating;
std::string ip; std::string ip;
std::string db; std::string db;
std::string username;
std::string password; std::string password;
int port; int port;
redis_pool_key_t key; redis_pool_key_t key;
redis_pool_elt(redis_pool_elt &&other) = default; redis_pool_elt(redis_pool_elt &&other) = default;


explicit redis_pool_elt(redis_pool *_pool, 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) const char *_ip, int _port)
: pool(_pool), ip(_ip), port(_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] == '/'; is_unix = ip[0] == '.' || ip[0] == '/';


if (_db) { if (_db) {
db = _db; db = _db;
} }
if( _username ) {
username = _username;
}
if (_password) { if (_password) {
password = _password; password = _password;
} }
conn->elt_pos = std::prev(std::end(terminating)); 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; rspamd_cryptobox_fast_hash_state_t st;


if (db) { if (db) {
rspamd_cryptobox_fast_hash_update(&st, db, strlen(db)); rspamd_cryptobox_fast_hash_update(&st, db, strlen(db));
} }
if (username) {
rspamd_cryptobox_fast_hash_update(&st, username, strlen(username));
}
if (password) { if (password) {
rspamd_cryptobox_fast_hash_update(&st, password, strlen(password)); rspamd_cryptobox_fast_hash_update(&st, password, strlen(password));
} }
cfg = _cfg; 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, auto release_connection(redisAsyncContext *ctx,
enum rspamd_redis_pool_release_type how) -> void; enum rspamd_redis_pool_release_type how) -> void;
redis_pool_connection::redis_pool_connection(redis_pool *_pool, redis_pool_connection::redis_pool_connection(redis_pool *_pool,
redis_pool_elt *_elt, redis_pool_elt *_elt,
const std::string &db, const std::string &db,
const std::string &username,
const std::string &password, const std::string &password,
struct redisAsyncContext *_ctx) struct redisAsyncContext *_ctx)
: ctx(_ctx), elt(_elt), pool(_pool) : ctx(_ctx), elt(_elt), pool(_pool)
redisLibevAttach(pool->event_loop, ctx); redisLibevAttach(pool->event_loop, ctx);
redisAsyncSetDisconnectCallback(ctx, redis_pool_connection::redis_on_disconnect); 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, redisAsyncCommand(ctx, nullptr, nullptr,
"AUTH %s", password.c_str()); "AUTH %s", password.c_str());
} }
auto *nctx = redis_async_new(); auto *nctx = redis_async_new();
if (nctx) { if (nctx) {
active.emplace_front(std::make_unique<redis_pool_connection>(pool, this, 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(); active.front()->elt_pos = active.begin();
} }


auto *nctx = redis_async_new(); auto *nctx = redis_async_new();
if (nctx) { if (nctx) {
active.emplace_front(std::make_unique<redis_pool_connection>(pool, this, 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(); active.front()->elt_pos = active.begin();
} }


RSPAMD_UNREACHABLE; 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) { 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); auto found_elt = elts_by_key.find(key);


if (found_elt != elts_by_key.end()) { if (found_elt != elts_by_key.end()) {
else { else {
/* Need to create a pool */ /* Need to create a pool */
auto nelt = elts_by_key.try_emplace(key, 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(); return nelt.first->second.new_connection();
} }


struct redisAsyncContext * struct redisAsyncContext *
rspamd_redis_pool_connect(void *p, 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); g_assert(p != NULL);
auto *pool = reinterpret_cast<class rspamd::redis_pool *>(p); 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);
} }





+ 2
- 1
src/libserver/redis_pool.h Ver arquivo

* Create or reuse the specific redis connection * Create or reuse the specific redis connection
* @param pool * @param pool
* @param db * @param db
* @param username
* @param password * @param password
* @param ip * @param ip
* @param port * @param port
*/ */
struct redisAsyncContext *rspamd_redis_pool_connect( struct redisAsyncContext *rspamd_redis_pool_connect(
void *pool, void *pool,
const gchar *db, const gchar *password,
const gchar *db, const gchar *username, const gchar *password,
const char *ip, int port); const char *ip, int port);


enum rspamd_redis_pool_release_type { enum rspamd_redis_pool_release_type {

+ 20
- 1
src/libstat/backends/redis_backend.c Ver arquivo

gint conf_ref; gint conf_ref;
struct rspamd_stat_async_elt *stat_elt; struct rspamd_stat_async_elt *stat_elt;
const gchar *redis_object; const gchar *redis_object;
const gchar *username;
const gchar *password; const gchar *password;
const gchar *dbname; const gchar *dbname;
gdouble timeout; gdouble timeout;
static void static void
rspamd_redis_maybe_auth(struct redis_stat_ctx *ctx, redisAsyncContext *redis) 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); redisAsyncCommand(redis, NULL, NULL, "AUTH %s", ctx->password);
} }
if (ctx->dbname) { if (ctx->dbname) {
} }
lua_pop(L, 1); 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_pushstring(L, "password");
lua_gettable(L, -2); lua_gettable(L, -2);
if (lua_type(L, -1) == LUA_TSTRING) { if (lua_type(L, -1) == LUA_TSTRING) {

+ 20
- 1
src/libstat/learn_cache/redis_cache.c Ver arquivo

struct rspamd_redis_cache_ctx { struct rspamd_redis_cache_ctx {
lua_State *L; lua_State *L;
struct rspamd_statfile_config *stcf; struct rspamd_statfile_config *stcf;
const gchar *username;
const gchar *password; const gchar *password;
const gchar *dbname; const gchar *dbname;
const gchar *redis_object; const gchar *redis_object;
rspamd_redis_cache_maybe_auth(struct rspamd_redis_cache_ctx *ctx, rspamd_redis_cache_maybe_auth(struct rspamd_redis_cache_ctx *ctx,
redisAsyncContext *redis) 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); redisAsyncCommand(redis, NULL, NULL, "AUTH %s", ctx->password);
} }
if (ctx->dbname) { if (ctx->dbname) {
} }
lua_pop(L, 1); 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_pushstring(L, "password");
lua_gettable(L, -2); lua_gettable(L, -2);
if (lua_type(L, -1) == LUA_TSTRING) { if (lua_type(L, -1) == LUA_TSTRING) {

+ 12
- 5
src/lua/lua_redis.c Ver arquivo

}; };


#define msg_debug_lua_redis(...) rspamd_conditional_debug_fast(NULL, NULL, \ #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) INIT_LOG_MODULE(lua_redis)


#define LUA_REDIS_SPECIFIC_REPLIED (1 << 0) #define LUA_REDIS_SPECIFIC_REPLIED (1 << 0)
struct rspamd_lua_ip *addr = NULL; struct rspamd_lua_ip *addr = NULL;
struct rspamd_task *task = NULL; struct rspamd_task *task = NULL;
const gchar *host = 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; gint cbref = -1;
struct rspamd_config *cfg = NULL; struct rspamd_config *cfg = NULL;
struct rspamd_async_session *session = NULL; struct rspamd_async_session *session = NULL;
} }
lua_pop(L, 1); 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_pushstring(L, "password");
lua_gettable(L, -2); lua_gettable(L, -2);
if (lua_type(L, -1) == LUA_TSTRING) { if (lua_type(L, -1) == LUA_TSTRING) {
if (ret) { if (ret) {
ud->terminated = 0; ud->terminated = 0;
ud->ctx = rspamd_redis_pool_connect(ud->pool, ud->ctx = rspamd_redis_pool_connect(ud->pool,
dbname, password,
dbname, username, password,
rspamd_inet_address_to_string(addr->addr), rspamd_inet_address_to_string(addr->addr),
rspamd_inet_address_get_port(addr->addr)); rspamd_inet_address_get_port(addr->addr));



+ 8
- 1
src/plugins/lua/bimi.lua Ver arquivo

if redis_params.db then if redis_params.db then
db = string.format('/%s', redis_params.db) db = string.format('/%s', redis_params.db)
end 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) password = string.format(':%s@', redis_params.password)
end end
local redis_server = string.format('redis://%s%s:%s%s', local redis_server = string.format('redis://%s%s:%s%s',

+ 8
- 0
src/rspamadm/fuzzy_convert.c Ver arquivo

static gchar *source_db = NULL; static gchar *source_db = NULL;
static gchar *redis_host = NULL; static gchar *redis_host = NULL;
static gchar *redis_db = NULL; static gchar *redis_db = NULL;
static gchar *redis_username = NULL;
static gchar *redis_password = NULL; static gchar *redis_password = NULL;
static int64_t fuzzy_expiry = 0; static int64_t fuzzy_expiry = 0;


"Output redis ip (in format ip:port)", NULL}, "Output redis ip (in format ip:port)", NULL},
{"dbname", 'D', 0, G_OPTION_ARG_STRING, &redis_db, {"dbname", 'D', 0, G_OPTION_ARG_STRING, &redis_db,
"Database in redis (should be numeric)", NULL}, "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", 'p', 0, G_OPTION_ARG_STRING, &redis_password,
"Password to connect to redis", NULL}, "Password to connect to redis", NULL},
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}}; {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}};
"-d: input sqlite\n" "-d: input sqlite\n"
"-h: output redis ip (in format ip:port)\n" "-h: output redis ip (in format ip:port)\n"
"-D: output redis database\n" "-D: output redis database\n"
"-u: redis username\n";
"-p: redis password\n"; "-p: redis password\n";
} }
else { else {
ucl_object_insert_key(obj, ucl_object_fromint(fuzzy_expiry), ucl_object_insert_key(obj, ucl_object_fromint(fuzzy_expiry),
"expiry", 0, false); "expiry", 0, false);


if (redis_username) {
ucl_object_insert_key(obj, ucl_object_fromstring(redis_username),
"redis_username", 0, false);
}
if (redis_password) { if (redis_password) {
ucl_object_insert_key(obj, ucl_object_fromstring(redis_password), ucl_object_insert_key(obj, ucl_object_fromstring(redis_password),
"redis_password", 0, false); "redis_password", 0, false);

+ 9
- 0
src/rspamadm/stat_convert.c Ver arquivo

/* Outputs */ /* Outputs */
static gchar *redis_host = NULL; static gchar *redis_host = NULL;
static gchar *redis_db = NULL; static gchar *redis_db = NULL;
static gchar *redis_username = NULL;
static gchar *redis_password = NULL; static gchar *redis_password = NULL;
static gboolean reset_previous = FALSE; static gboolean reset_previous = FALSE;


"Input learn cache", NULL}, "Input learn cache", NULL},
{"redis-host", 'h', 0, G_OPTION_ARG_STRING, &redis_host, {"redis-host", 'h', 0, G_OPTION_ARG_STRING, &redis_host,
"Output redis ip (in format ip:port)", NULL}, "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, {"redis-password", 'p', 0, G_OPTION_ARG_STRING, &redis_password,
"Password to connect to redis", NULL}, "Password to connect to redis", NULL},
{"redis-db", 'd', 0, G_OPTION_ARG_STRING, &redis_db, {"redis-db", 'd', 0, G_OPTION_ARG_STRING, &redis_db,
"** Or specify options directly **\n" "** Or specify options directly **\n"
"--redis-host: output redis ip (in format ip:port)\n" "--redis-host: output redis ip (in format ip:port)\n"
"--redis-db: output redis database\n" "--redis-db: output redis database\n"
"--redis-username: redis username\n"
"--redis-password: redis password\n" "--redis-password: redis password\n"
"--cache: sqlite3 file for learn cache\n" "--cache: sqlite3 file for learn cache\n"
"--spam-db: sqlite3 input file for spam data\n" "--spam-db: sqlite3 input file for spam data\n"
"dbname", 0, false); "dbname", 0, false);
} }


if (redis_username) {
ucl_object_insert_key(redis, ucl_object_fromstring(redis_username),
"username", 0, false);
}

if (redis_password) { if (redis_password) {
ucl_object_insert_key(redis, ucl_object_fromstring(redis_password), ucl_object_insert_key(redis, ucl_object_fromstring(redis_password),
"password", 0, false); "password", 0, false);

Carregando…
Cancelar
Salvar