]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow to quarantine rejected messages using milter interface
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 23 Nov 2017 20:02:32 +0000 (20:02 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 23 Nov 2017 20:02:32 +0000 (20:02 +0000)
src/libserver/milter.c
src/libserver/milter.h
src/libserver/milter_internal.h
src/rspamd_proxy.c

index f2ced4f0fae263cffe497d1fa22691cf12035936..7874a9dbcd314730043e5d698d115c2e8f717c3e 100644 (file)
@@ -50,6 +50,7 @@ struct rspamd_milter_context {
        gchar *spam_header;
        void *sessions_cache;
        gboolean discard_on_reject;
+       gboolean quarantine_on_reject;
 };
 
 static struct rspamd_milter_context *milter_ctx = NULL;
@@ -1072,6 +1073,7 @@ rspamd_milter_handle_socket (gint fd, const struct timeval *tv,
        priv->state = RSPAMD_MILTER_READ_MORE;
        priv->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "milter");
        priv->discard_on_reject = milter_ctx->discard_on_reject;
+       priv->quarantine_on_reject = milter_ctx->quarantine_on_reject;
 
        if (pool) {
                /* Copy tag */
@@ -1567,8 +1569,13 @@ rspamd_milter_process_milter_block (struct rspamd_milter_session *session,
                                priv->discard_on_reject = TRUE;
                                msg_info_milter ("discard message instead of rejection");
                        }
+                       else if (strcmp (ucl_object_tostring (elt), "quarantine") == 0) {
+                               priv->quarantine_on_reject = TRUE;
+                               msg_info_milter ("quarantine message instead of rejection");
+                       }
                        else {
                                priv->discard_on_reject = FALSE;
+                               priv->quarantine_on_reject = FALSE;
                        }
                }
 
@@ -1713,6 +1720,10 @@ rspamd_milter_send_task_results (struct rspamd_milter_session *session,
                if (priv->discard_on_reject) {
                        rspamd_milter_send_action (session, RSPAMD_MILTER_DISCARD);
                }
+               else if (priv->quarantine_on_reject) {
+                       /* TODO: need to add quarantine message */
+                       rspamd_milter_send_action (session, RSPAMD_MILTER_QUARANTINE);
+               }
                else {
                        rcode = rspamd_fstring_new_init (RSPAMD_MILTER_RCODE_REJECT,
                                        sizeof (RSPAMD_MILTER_RCODE_REJECT) - 1);
@@ -1789,7 +1800,7 @@ cleanup:
 
 void
 rspamd_milter_init_library (const gchar *spam_header, void *sessions_cache,
-               gboolean discard_on_reject)
+               gboolean discard_on_reject, gboolean quarantine_on_reject)
 {
        if (milter_ctx) {
                g_free (milter_ctx->spam_header);
@@ -1807,6 +1818,7 @@ rspamd_milter_init_library (const gchar *spam_header, void *sessions_cache,
 
        milter_ctx->sessions_cache = sessions_cache;
        milter_ctx->discard_on_reject = discard_on_reject;
+       milter_ctx->quarantine_on_reject = quarantine_on_reject;
 }
 
 rspamd_mempool_t *
index 8769a8230e1c9ffca1f65ac5180f75b5990c502f..eae99eff21a400baae7cd538001ec650c6f44db2 100644 (file)
@@ -36,7 +36,8 @@ enum rspamd_milter_reply {
        RSPAMD_MILTER_TEMPFAIL = 't',
        RSPAMD_MILTER_REPLYCODE = 'y',
        RSPAMD_MILTER_OPTNEG = 'O',
-       RSPAMD_MILTER_PROGRESS = 'p'
+       RSPAMD_MILTER_PROGRESS = 'p',
+       RSPAMD_MILTER_QUARANTINE = 'q',
 };
 
 struct rspamd_email_address;
@@ -151,7 +152,8 @@ void rspamd_milter_send_task_results (struct rspamd_milter_session *session,
  * @param spam_header spam header name (must NOT be NULL)
  */
 void rspamd_milter_init_library (const gchar *spam_header,
-               void *sessions_cache, gboolean discard_on_reject);
+               void *sessions_cache, gboolean discard_on_reject,
+               gboolean quarantine_on_reject);
 
 /**
  * Returns pool for a session
index 9087bdbfb1ce00b799e65fec52be6176281586f7..6473ed14779bd9fe75b1afe42c11237e33105ef9 100644 (file)
@@ -67,6 +67,7 @@ struct rspamd_milter_private {
        enum rspamd_milter_io_state state;
        int fd;
        gboolean discard_on_reject;
+       gboolean quarantine_on_reject;
        gboolean no_action;
 };
 
@@ -124,10 +125,12 @@ enum rspamd_milter_io_cmd {
 #define RSPAMD_MILTER_FLAG_ADDRCPT     (1L<<2) /* filter may add recipients */
 #define RSPAMD_MILTER_FLAG_DELRCPT     (1L<<3) /* filter may delete recipients */
 #define RSPAMD_MILTER_FLAG_CHGHDRS     (1L<<4) /* filter may change/delete headers */
+#define RSPAMD_MILTER_FLAG_QUARANTINE  (1L<<5) /* filter may request quarantine */
 
 #define RSPAMD_MILTER_ACTIONS_MASK \
        (RSPAMD_MILTER_FLAG_ADDHDRS | RSPAMD_MILTER_FLAG_ADDRCPT | \
-       RSPAMD_MILTER_FLAG_DELRCPT | RSPAMD_MILTER_FLAG_CHGHDRS)
+       RSPAMD_MILTER_FLAG_DELRCPT | RSPAMD_MILTER_FLAG_CHGHDRS | \
+       RSPAMD_MILTER_FLAG_QUARANTINE)
 
 enum rspamd_milter_connect_proto {
        RSPAMD_MILTER_CONN_UNKNOWN = 'U',
index 6223d32efad50fc99521e0ac89dcc6fa74b0a75f..5b2206be4780b82254ab4472fc186c5c19e26583 100644 (file)
@@ -138,6 +138,8 @@ struct rspamd_proxy_ctx {
        gboolean milter;
        /* Discard messages instead of rejecting them */
        gboolean discard_on_reject;
+       /* Quarantine messages instead of rejecting them */
+       gboolean quarantine_on_reject;
        /* Milter spam header */
        gchar *spam_header;
        /* Sessions cache */
@@ -810,6 +812,14 @@ init_rspamd_proxy (struct rspamd_config *cfg)
                        G_STRUCT_OFFSET (struct rspamd_proxy_ctx, discard_on_reject),
                        0,
                        "Tell MTA to discard rejected messages silently");
+       rspamd_rcl_register_worker_option (cfg,
+                       type,
+                       "quarantine_on_reject",
+                       rspamd_rcl_parse_struct_boolean,
+                       ctx,
+                       G_STRUCT_OFFSET (struct rspamd_proxy_ctx, quarantine_on_reject),
+                       0,
+                       "Tell MTA to quarantine rejected messages");
        rspamd_rcl_register_worker_option (cfg,
                        type,
                        "spam_header",
@@ -2115,7 +2125,7 @@ start_rspamd_proxy (struct rspamd_worker *worker) {
        }
 
        rspamd_milter_init_library (ctx->spam_header, ctx->sessions_cache,
-                       ctx->discard_on_reject);
+                       ctx->discard_on_reject, ctx->quarantine_on_reject);
        rspamd_lua_run_postloads (ctx->cfg->lua_state, ctx->cfg, ctx->ev_base,
                        worker);