]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow custom milter quarantine and tempfail messages 4901/head
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 2 Apr 2024 14:39:59 +0000 (15:39 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 2 Apr 2024 14:39:59 +0000 (15:39 +0100)
Issue: #4892
Closes: #4892
src/libserver/milter.c
src/libserver/milter.h
src/rspamd_proxy.c

index dd64822c432f78c112fa8ec8d3d85af29478d83b..f35278a0e4dbbe872166bdafed842022823ed50b 100644 (file)
@@ -1288,9 +1288,10 @@ rspamd_milter_send_action(struct rspamd_milter_session *session,
        rspamd_fstring_t *reply = NULL;
        gsize len;
        GString *name, *value;
-       const char *reason, *body_str;
+       const char *body_str;
        struct rspamd_milter_outbuf *obuf;
        struct rspamd_milter_private *priv = session->priv;
+       const rspamd_fstring_t *reason;
 
        va_start(ap, act);
        cmd = act;
@@ -1307,16 +1308,21 @@ rspamd_milter_send_action(struct rspamd_milter_session *session,
                SET_COMMAND(cmd, 0, reply, pos);
                break;
        case RSPAMD_MILTER_QUARANTINE:
-               reason = va_arg(ap, const char *);
+               reason = va_arg(ap, const rspamd_fstring_t *);
 
-               if (reason == NULL) {
-                       reason = "";
+               if (reason != NULL) {
+                       len = reason->len;
+                       msg_debug_milter("send quarantine action %*s", (int) len, reason->str);
+                       SET_COMMAND(cmd, len + 1, reply, pos);
+                       memcpy(pos, reason->str, len);
+                       pos[len] = '\0';
+               }
+               else {
+                       msg_debug_milter("send quarantine action with no specific string");
+                       SET_COMMAND(cmd, 1, reply, pos);
+                       *pos = '\0';
                }
 
-               len = strlen(reason);
-               msg_debug_milter("send quarantine action %s", reason);
-               SET_COMMAND(cmd, len + 1, reply, pos);
-               memcpy(pos, reason, len + 1);
                break;
        case RSPAMD_MILTER_ADDHEADER:
                name = va_arg(ap, GString *);
@@ -2119,9 +2125,18 @@ void rspamd_milter_send_task_results(struct rspamd_milter_session *session,
                        rspamd_milter_send_action(session, RSPAMD_MILTER_DISCARD);
                }
                else if (priv->quarantine_on_reject) {
-                       /* TODO: be more flexible about SMTP messages */
-                       rspamd_milter_send_action(session, RSPAMD_MILTER_QUARANTINE,
-                                                                         RSPAMD_MILTER_QUARANTINE_MESSAGE);
+                       if (!reply) {
+                               if (milter_ctx->quarantine_message == NULL) {
+                                       reply = rspamd_fstring_new_init(
+                                               RSPAMD_MILTER_QUARANTINE_MESSAGE,
+                                               sizeof(RSPAMD_MILTER_QUARANTINE_MESSAGE) - 1);
+                               }
+                               else {
+                                       reply = rspamd_fstring_new_init(milter_ctx->quarantine_message,
+                                                                                                       strlen(milter_ctx->quarantine_message));
+                               }
+                               rspamd_milter_send_action(session, RSPAMD_MILTER_QUARANTINE, reply);
+                       }
 
                        /* Quarantine also requires accept action, all hail Sendmail */
                        rspamd_milter_send_action(session, RSPAMD_MILTER_ACCEPT);
@@ -2154,8 +2169,15 @@ void rspamd_milter_send_task_results(struct rspamd_milter_session *session,
                                                                                sizeof(RSPAMD_MILTER_XCODE_TEMPFAIL) - 1);
 
                if (!reply) {
-                       reply = rspamd_fstring_new_init(RSPAMD_MILTER_TEMPFAIL_MESSAGE,
-                                                                                       sizeof(RSPAMD_MILTER_TEMPFAIL_MESSAGE) - 1);
+                       if (milter_ctx->tempfail_message == NULL) {
+                               reply = rspamd_fstring_new_init(
+                                       RSPAMD_MILTER_TEMPFAIL_MESSAGE,
+                                       sizeof(RSPAMD_MILTER_TEMPFAIL_MESSAGE) - 1);
+                       }
+                       else {
+                               reply = rspamd_fstring_new_init(milter_ctx->tempfail_message,
+                                                                                               strlen(milter_ctx->tempfail_message));
+                       }
                }
 
                rspamd_milter_set_reply(session, rcode, xcode, reply);
@@ -2193,9 +2215,18 @@ void rspamd_milter_send_task_results(struct rspamd_milter_session *session,
                break;
 
        case METRIC_ACTION_QUARANTINE:
-               /* TODO: be more flexible about SMTP messages */
-               rspamd_milter_send_action(session, RSPAMD_MILTER_QUARANTINE,
-                                                                 RSPAMD_MILTER_QUARANTINE_MESSAGE);
+               if (!reply) {
+                       if (milter_ctx->quarantine_message == NULL) {
+                               reply = rspamd_fstring_new_init(
+                                       RSPAMD_MILTER_QUARANTINE_MESSAGE,
+                                       sizeof(RSPAMD_MILTER_QUARANTINE_MESSAGE) - 1);
+                       }
+                       else {
+                               reply = rspamd_fstring_new_init(milter_ctx->quarantine_message,
+                                                                                               strlen(milter_ctx->quarantine_message));
+                       }
+                       rspamd_milter_send_action(session, RSPAMD_MILTER_QUARANTINE, reply);
+               }
 
                /* Quarantine also requires accept action, all hail Sendmail */
                rspamd_milter_send_action(session, RSPAMD_MILTER_ACCEPT);
index 840f69126adb3a716d9719669ef632eb194255ac..5b4b750e23dd9ffdefd1276d02f940037653c23d 100644 (file)
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2017 Vsevolod Stakhov
+/*
+ * Copyright 2024 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -55,6 +55,8 @@ struct rspamd_milter_context {
        const char *spam_header;
        const char *client_ca_name;
        const char *reject_message;
+       const char *quarantine_message;
+       const char *tempfail_message;
        void *sessions_cache;
        struct rspamd_config *cfg;
        gboolean discard_on_reject;
index 39df7c98d10d1668ccdfb49fddae6b674faa9c59..415d22f07805bfd6e1f27bb77eefdabd01614aba 100644 (file)
@@ -150,8 +150,10 @@ struct rspamd_proxy_ctx {
        char *spam_header;
        /* CA name that can be used for client certificates */
        char *client_ca_name;
-       /* Milter rejection message */
+       /* Milter messages */
        char *reject_message;
+       char *quarantine_message;
+       char *tempfail_message;
        /* Sessions cache */
        void *sessions_cache;
        struct rspamd_milter_context milter_ctx;
@@ -874,6 +876,22 @@ init_rspamd_proxy(struct rspamd_config *cfg)
                                                                          G_STRUCT_OFFSET(struct rspamd_proxy_ctx, reject_message),
                                                                          0,
                                                                          "Use custom rejection message");
+       rspamd_rcl_register_worker_option(cfg,
+                                                                         type,
+                                                                         "quarantine_message",
+                                                                         rspamd_rcl_parse_struct_string,
+                                                                         ctx,
+                                                                         G_STRUCT_OFFSET(struct rspamd_proxy_ctx, quarantine_message),
+                                                                         0,
+                                                                         "Use custom quarantine message");
+       rspamd_rcl_register_worker_option(cfg,
+                                                                         type,
+                                                                         "tempfail_message",
+                                                                         rspamd_rcl_parse_struct_string,
+                                                                         ctx,
+                                                                         G_STRUCT_OFFSET(struct rspamd_proxy_ctx, tempfail_message),
+                                                                         0,
+                                                                         "Use custom tempfail message");
 
        return ctx;
 }
@@ -2435,6 +2453,8 @@ start_rspamd_proxy(struct rspamd_worker *worker)
        ctx->milter_ctx.sessions_cache = ctx->sessions_cache;
        ctx->milter_ctx.client_ca_name = ctx->client_ca_name;
        ctx->milter_ctx.reject_message = ctx->reject_message;
+       ctx->milter_ctx.quarantine_message = ctx->quarantine_message;
+       ctx->milter_ctx.tempfail_message = ctx->tempfail_message;
        ctx->milter_ctx.cfg = ctx->cfg;
        rspamd_milter_init_library(&ctx->milter_ctx);