diff options
-rw-r--r-- | interface/js/rspamd.js | 10 | ||||
-rw-r--r-- | src/libmime/message.h | 1 | ||||
-rw-r--r-- | src/lua/lua_redis.c | 66 | ||||
-rw-r--r-- | src/lua/lua_task.c | 11 | ||||
-rw-r--r-- | src/ragel/smtp_received.rl | 2 | ||||
-rw-r--r-- | src/ragel/smtp_received_parser.rl | 20 |
6 files changed, 71 insertions, 39 deletions
diff --git a/interface/js/rspamd.js b/interface/js/rspamd.js index d4a1da70f..cfbf59da7 100644 --- a/interface/js/rspamd.js +++ b/interface/js/rspamd.js @@ -1048,6 +1048,16 @@ displayUI(); return; } + $.ajax({ + type: 'GET', + url: 'stat', + success: function () { + saveCredentials({}, 'nopassword'); + $(dialog).hide(); + $(backdrop).hide(); + displayUI(); + }, + }); var nav = $('#navBar'); var ui = $('#mainUI'); var dialog = $('#connectDialog'); diff --git a/src/libmime/message.h b/src/libmime/message.h index 2a9201be8..e38420dbf 100644 --- a/src/libmime/message.h +++ b/src/libmime/message.h @@ -84,6 +84,7 @@ struct received_header { gchar *real_hostname; gchar *real_ip; gchar *by_hostname; + gchar *for_mbox; rspamd_inet_addr_t *addr; time_t timestamp; enum rspamd_received_type type; diff --git a/src/lua/lua_redis.c b/src/lua/lua_redis.c index a115708e3..8bc6004f2 100644 --- a/src/lua/lua_redis.c +++ b/src/lua/lua_redis.c @@ -95,6 +95,7 @@ struct lua_redis_userdata { redisAsyncContext *ctx; lua_State *L; struct rspamd_task *task; + struct rspamd_redis_pool *pool; gchar *server; gchar *reqline; struct lua_redis_specific_userdata *specific; @@ -113,6 +114,7 @@ struct lua_redis_specific_userdata { struct lua_redis_specific_userdata *next; struct event timeout; gboolean replied; + gboolean finished; }; struct lua_redis_ctx { @@ -152,7 +154,7 @@ lua_redis_dtor (struct lua_redis_ctx *ctx) { struct lua_redis_userdata *ud; struct lua_redis_specific_userdata *cur, *tmp; - gboolean is_connected = FALSE, is_successfull = TRUE; + gboolean is_successfull = TRUE; struct redisAsyncContext *ac; if (ctx->async) { @@ -162,28 +164,19 @@ lua_redis_dtor (struct lua_redis_ctx *ctx) if (ud->ctx) { LL_FOREACH_SAFE (ud->specific, cur, tmp) { - if (is_connected) { - event_del (&cur->timeout); - } + event_del (&cur->timeout); if (!cur->replied) { is_successfull = FALSE; } + + cur->finished = TRUE; } ud->terminated = 1; - /* - * On calling of redisFree, hiredis calls for callbacks pending - * Hence, to avoid double free, we ensure that the object must - * still be alive here! - */ - ctx->ref.refcount = 100500; ac = ud->ctx; ud->ctx = NULL; - rspamd_redis_pool_release_connection (ud->task->cfg->redis_pool, - ac, is_successfull); - ctx->ref.refcount = 0; - is_connected = TRUE; + rspamd_redis_pool_release_connection (ud->pool, ac, is_successfull); } LL_FOREACH_SAFE (ud->specific, cur, tmp) { @@ -226,7 +219,7 @@ lua_redis_fin (void *arg) ctx = sp_ud->ctx; event_del (&sp_ud->timeout); msg_debug ("finished redis query %p from session %p", sp_ud, ctx); - sp_ud->c->terminated = TRUE; + sp_ud->finished = TRUE; REDIS_RELEASE (ctx); } @@ -245,8 +238,8 @@ lua_redis_push_error (const gchar *err, struct rspamd_task **ptask; struct lua_redis_userdata *ud = sp_ud->c; - if (!sp_ud->replied) { - if (sp_ud->cbref != -1) { + if (!sp_ud->replied && !sp_ud->finished) { + if (sp_ud->cbref != -1 && ud->task) { /* Push error */ lua_rawgeti (ud->L, LUA_REGISTRYINDEX, sp_ud->cbref); ptask = lua_newuserdata (ud->L, sizeof (struct rspamd_task *)); @@ -264,7 +257,7 @@ lua_redis_push_error (const gchar *err, } sp_ud->replied = TRUE; - if (connected) { + if (connected && ud->task) { rspamd_session_watcher_pop (ud->task->s, sp_ud->w); rspamd_session_remove_event (ud->task->s, lua_redis_fin, sp_ud); } @@ -313,8 +306,8 @@ lua_redis_push_data (const redisReply *r, struct lua_redis_ctx *ctx, struct rspamd_task **ptask; struct lua_redis_userdata *ud = sp_ud->c; - if (!sp_ud->replied) { - if (sp_ud->cbref != -1) { + if (!sp_ud->replied && !sp_ud->finished) { + if (sp_ud->cbref != -1 && ud->task) { /* Push error */ lua_rawgeti (ud->L, LUA_REGISTRYINDEX, sp_ud->cbref); ptask = lua_newuserdata (ud->L, sizeof (struct rspamd_task *)); @@ -334,8 +327,11 @@ lua_redis_push_data (const redisReply *r, struct lua_redis_ctx *ctx, } sp_ud->replied = TRUE; - rspamd_session_watcher_pop (ud->task->s, sp_ud->w); - rspamd_session_remove_event (ud->task->s, lua_redis_fin, sp_ud); + + if (ud->task) { + rspamd_session_watcher_pop (ud->task->s, sp_ud->w); + rspamd_session_remove_event (ud->task->s, lua_redis_fin, sp_ud); + } } } @@ -357,7 +353,7 @@ lua_redis_callback (redisAsyncContext *c, gpointer r, gpointer priv) ctx = sp_ud->ctx; ud = sp_ud->c; - if (ud->terminated) { + if (ud->terminated || sp_ud->finished) { /* We are already at the termination stage, just go out */ return; } @@ -396,8 +392,7 @@ lua_redis_callback (redisAsyncContext *c, gpointer r, gpointer priv) ud->ctx = NULL; if (ac) { - rspamd_redis_pool_release_connection (ud->task->cfg->redis_pool, - ac, FALSE); + rspamd_redis_pool_release_connection (ud->pool, ac, FALSE); } } @@ -411,6 +406,10 @@ lua_redis_timeout (int fd, short what, gpointer u) struct lua_redis_ctx *ctx; redisAsyncContext *ac; + if (sp_ud->finished) { + return; + } + ctx = sp_ud->ctx; REDIS_RETAIN (ctx); @@ -427,9 +426,9 @@ lua_redis_timeout (int fd, short what, gpointer u) * This will call all callbacks pending so the entire context * will be destructed */ - rspamd_redis_pool_release_connection (sp_ud->c->task->cfg->redis_pool, - ac, TRUE); + rspamd_redis_pool_release_connection (sp_ud->c->pool, ac, TRUE); } + REDIS_RELEASE (ctx); } @@ -587,6 +586,7 @@ lua_redis_make_request (lua_State *L) ctx->async = TRUE; ud = &ctx->d.async; ud->task = task; + ud->pool = task->cfg->redis_pool; ud->L = L; sp_ud = g_slice_alloc0 (sizeof (*sp_ud)); @@ -621,6 +621,7 @@ lua_redis_make_request (lua_State *L) ctx->async = TRUE; ud = &ctx->d.async; ud->task = task; + ud->pool = task->cfg->redis_pool; ud->L = L; args_pos = 3; @@ -661,7 +662,7 @@ lua_redis_make_request (lua_State *L) if (ret) { ud->terminated = 0; ud->timeout = timeout; - ud->ctx = rspamd_redis_pool_connect (task->cfg->redis_pool, + ud->ctx = rspamd_redis_pool_connect (ud->pool, dbname, password, rspamd_inet_address_to_string (addr->addr), rspamd_inet_address_get_port (addr->addr)); @@ -670,8 +671,7 @@ lua_redis_make_request (lua_State *L) if (ud->ctx) { msg_err_task_check ("cannot connect to redis: %s", ud->ctx->errstr); - rspamd_redis_pool_release_connection (task->cfg->redis_pool, - ud->ctx, TRUE); + rspamd_redis_pool_release_connection (ud->pool, ud->ctx, TRUE); ud->ctx = NULL; } else { @@ -711,8 +711,7 @@ lua_redis_make_request (lua_State *L) } else { msg_info_task_check ("call to redis failed: %s", ud->ctx->errstr); - rspamd_redis_pool_release_connection (task->cfg->redis_pool, - ud->ctx, TRUE); + rspamd_redis_pool_release_connection (ud->pool, ud->ctx, TRUE); ud->ctx = NULL; REDIS_RELEASE (ctx); ret = FALSE; @@ -921,6 +920,7 @@ lua_redis_connect (lua_State *L) ctx->async = TRUE; ud = &ctx->d.async; ud->task = task; + ud->pool = task->cfg->redis_pool; ud->L = L; ret = TRUE; } @@ -929,7 +929,7 @@ lua_redis_connect (lua_State *L) if (ret && ctx) { ud->terminated = 0; ud->timeout = timeout; - ud->ctx = rspamd_redis_pool_connect (task->cfg->redis_pool, + ud->ctx = rspamd_redis_pool_connect (ud->pool, NULL, NULL, rspamd_inet_address_to_string (addr->addr), rspamd_inet_address_get_port (addr->addr)); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index db10abe01..8da6d3f16 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -250,6 +250,9 @@ LUA_FUNCTION_DEF (task, get_raw_headers); * - `real_hostname` - hostname as resolved by MTA * - `real_ip` - string representation of IP as resolved by PTR request of MTA * - `by_hostname` - MTA hostname + * - `proto` - protocol, e.g. ESMTP or ESMTPS + * - `timestamp` - received timetamp + * - `for` - for value (unparsed mailbox) * * Please note that in some situations rspamd cannot parse all the fields of received headers. * In that case you should check all strings for validity. @@ -1499,7 +1502,7 @@ lua_task_get_received_headers (lua_State * L) guint i, k = 1; if (task) { - lua_newtable (L); + lua_createtable (L, task->received->len, 0); for (i = 0; i < task->received->len; i ++) { rh = g_ptr_array_index (task->received, i); @@ -1507,11 +1510,12 @@ lua_task_get_received_headers (lua_State * L) if (G_UNLIKELY (rh->from_ip == NULL && rh->real_ip == NULL && rh->real_hostname == NULL && - rh->by_hostname == NULL && rh->timestamp == 0)) { + rh->by_hostname == NULL && rh->timestamp == 0 && + rh->for_mbox == NULL)) { continue; } - lua_newtable (L); + lua_createtable (L, 0, 8); rspamd_lua_table_set (L, "from_hostname", rh->from_hostname); rspamd_lua_table_set (L, "from_ip", rh->from_ip); rspamd_lua_table_set (L, "real_hostname", rh->real_hostname); @@ -1555,6 +1559,7 @@ lua_task_get_received_headers (lua_State * L) lua_settable (L, -3); rspamd_lua_table_set (L, "by_hostname", rh->by_hostname); + rspamd_lua_table_set (L, "for", rh->for_mbox); lua_rawseti (L, -2, k ++); } } diff --git a/src/ragel/smtp_received.rl b/src/ragel/smtp_received.rl index e005dcc9c..c1fd46703 100644 --- a/src/ragel/smtp_received.rl +++ b/src/ragel/smtp_received.rl @@ -44,7 +44,7 @@ msg_id = "<" id_left "@" id_right ">"; ID = CFWS "ID"i FWS ( Atom | msg_id ); - For = CFWS "FOR"i FWS ( Path | Mailbox ) %For_End; + For = CFWS "FOR"i FWS ( Path | Mailbox ) >For_Start %For_End; Additional_Registered_Clauses = CFWS Atom FWS String; Opt_info = Via? With? ID? For? Additional_Registered_Clauses?; # Here we make From part optional just because many received headers lack it diff --git a/src/ragel/smtp_received_parser.rl b/src/ragel/smtp_received_parser.rl index b2c73cab3..c599e0495 100644 --- a/src/ragel/smtp_received_parser.rl +++ b/src/ragel/smtp_received_parser.rl @@ -142,6 +142,8 @@ reported_ip_end = NULL; ip_start = NULL; ip_end = NULL; + for_start = NULL; + for_end = NULL; } action By_Start { @@ -155,6 +157,8 @@ reported_ip_end = NULL; ip_start = NULL; ip_end = NULL; + for_start = NULL; + for_end = NULL; } action By_End { @@ -210,8 +214,17 @@ } } - action For_End { + action For_Start { + for_start = p; + } + action For_End { + if (for_start && p > for_start) { + for_end = p; + len = for_end - for_start; + rh->for_mbox = rspamd_mempool_alloc (task->task_pool, len + 1); + rspamd_strlcpy (rh->for_mbox, for_start, len + 1); + } } action SMTP_proto { @@ -270,7 +283,8 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l *real_ip_start, *real_ip_end, *reported_domain_start, *reported_domain_end, *reported_ip_start, *reported_ip_end, - *ip_start, *ip_end, *date_start; + *ip_start, *ip_end, *date_start, + *for_start, *for_end; const char *p = data, *pe = data + len, *eof; int cs, in_v6 = 0, *stack = NULL; gsize top = 0; @@ -292,6 +306,8 @@ rspamd_smtp_recieved_parse (struct rspamd_task *task, const char *data, size_t l ip_start = NULL; ip_end = NULL; date_start = NULL; + for_start = NULL; + for_end = NULL; rh->type = RSPAMD_RECEIVED_UNKNOWN; memset (&for_addr, 0, sizeof (for_addr)); |