From: Vsevolod Stakhov Date: Sat, 29 Apr 2017 11:39:36 +0000 (+0100) Subject: [Minor] Add options negotiation stage for milter protocol X-Git-Tag: 1.6.0~298 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=852ec8126ca249debc59c5038ac58d5cbe96338f;p=rspamd.git [Minor] Add options negotiation stage for milter protocol --- diff --git a/src/libserver/milter.c b/src/libserver/milter.c index e90d05f3e..20bd4ba98 100644 --- a/src/libserver/milter.c +++ b/src/libserver/milter.c @@ -68,6 +68,8 @@ rspamd_milter_session_dtor (struct rspamd_milter_session *session) { struct rspamd_milter_outbuf *obuf, *obuf_tmp; struct rspamd_milter_private *priv; + struct rspamd_email_address *cur; + guint i; if (session) { priv = session->priv; @@ -84,6 +86,38 @@ rspamd_milter_session_dtor (struct rspamd_milter_session *session) rspamd_fstring_free (priv->parser.buf); } + if (session->message) { + rspamd_fstring_free (session->message); + } + + if (session->addr) { + rspamd_inet_address_destroy (session->addr); + } + + if (session->rcpts) { + PTR_ARRAY_FOREACH (session->rcpts, i, cur) { + rspamd_email_address_unref (cur); + } + + g_ptr_array_free (session->rcpts, TRUE); + } + + if (session->from) { + rspamd_email_address_unref (session->from); + } + + if (session->macros) { + g_hash_table_unref (session->macros); + } + + if (session->helo) { + rspamd_fstring_free (session->helo); + } + + if (session->hostname) { + rspamd_fstring_free (session->hostname); + } + priv->out_chain = NULL; } } @@ -177,12 +211,38 @@ rspamd_milter_process_command (struct rspamd_milter_session *session, READ_INT_32 (pos, version); READ_INT_32 (pos, actions); READ_INT_32 (pos, protocol); + + msg_debug_milter ("optneg: version: %d, actions: %d, protocol: %d", + version, actions, protocol); + + if (version < RSPAMD_MILTER_PROTO_VER) { + msg_warn_milter ("MTA specifies too old protocol: %d, " + "aborting connnection", version); + + err = g_error_new (rspamd_milter_quark (), EINVAL, "invalid " + "protocol version: %d", version); + rspamd_milter_on_protocol_error (session, priv, err); + + return FALSE; + } + + version = RSPAMD_MILTER_PROTO_VER; + actions |= RSPAMD_MILTER_ACTIONS_MASK; + protocol = RSPAMD_MILTER_FLAG_NOREPLY_MASK; + + return rspamd_milter_send_action (session, RSPAMD_MILTER_OPTNEG, + version, actions, protocol); break; case RSPAMD_MILTER_CMD_QUIT: break; case RSPAMD_MILTER_CMD_RCPT: break; case RSPAMD_MILTER_CMD_DATA: + if (!session->message) { + session->message = rspamd_fstring_sized_new ( + RSPAMD_MILTER_MESSAGE_CHUNK); + } + /* We do not need reply as specified */ break; default: break; diff --git a/src/libserver/milter_internal.h b/src/libserver/milter_internal.h index 9d3b05c00..9a99ad836 100644 --- a/src/libserver/milter_internal.h +++ b/src/libserver/milter_internal.h @@ -82,4 +82,53 @@ enum rspamd_milter_io_cmd { RSPAMD_MILTER_CMD_UNKNOWN = 'U' /* Any unknown command */ }; +/* + * Protocol flags + */ +#define RSPAMD_MILTER_FLAG_NOUNKNOWN (1L<<8) /* filter does not want unknown cmd */ +#define RSPAMD_MILTER_FLAG_NODATA (1L<<9) /* filter does not want DATA */ +#define RSPAMD_MILTER_FLAG_NR_HDR (1L<<7) /* filter won't reply for header */ +#define RSPAMD_MILTER_FLAG_SKIP (1L<<10)/* MTA supports SMFIR_SKIP */ +#define RSPAMD_MILTER_FLAG_RCPT_REJ (1L<<11)/* filter wants rejected RCPTs */ +#define RSPAMD_MILTER_FLAG_NR_CONN (1L<<12)/* filter won't reply for connect */ +#define RSPAMD_MILTER_FLAG_NR_HELO (1L<<13)/* filter won't reply for HELO */ +#define RSPAMD_MILTER_FLAG_NR_MAIL (1L<<14)/* filter won't reply for MAIL */ +#define RSPAMD_MILTER_FLAG_NR_RCPT (1L<<15)/* filter won't reply for RCPT */ +#define RSPAMD_MILTER_FLAG_NR_DATA (1L<<16)/* filter won't reply for DATA */ +#define RSPAMD_MILTER_FLAG_NR_UNKN (1L<<17)/* filter won't reply for UNKNOWN */ +#define RSPAMD_MILTER_FLAG_NR_EOH (1L<<18)/* filter won't reply for eoh */ +#define RSPAMD_MILTER_FLAG_NR_BODY (1L<<19)/* filter won't reply for body chunk */ + +/* + * For now, we specify that we want to reply just after EOM + */ +#define RSPAMD_MILTER_FLAG_NOREPLY_MASK \ + (RSPAMD_MILTER_FLAG_NR_CONN | RSPAMD_MILTER_FLAG_NR_HELO | \ + RSPAMD_MILTER_FLAG_NR_MAIL | RSPAMD_MILTER_FLAG_NR_RCPT | \ + RSPAMD_MILTER_FLAG_NR_DATA | RSPAMD_MILTER_FLAG_NR_UNKN | \ + RSPAMD_MILTER_FLAG_NR_HDR | RSPAMD_MILTER_FLAG_NR_EOH | \ + RSPAMD_MILTER_FLAG_NR_BODY) + +/* + * Options that the filter may send at initial handshake time, and message + * modifications that the filter may request at the end of the message body. + */ +#define RSPAMD_MILTER_FLAG_ADDHDRS (1L<<0) /* filter may add headers */ +#define RSPAMD_MILTER_FLAG_CHGBODY (1L<<1) /* filter may replace body */ +#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_ACTIONS_MASK \ + (RSPAMD_MILTER_FLAG_ADDHDRS | RSPAMD_MILTER_FLAG_ADDRCPT | \ + RSPAMD_MILTER_FLAG_DELRCPT | RSPAMD_MILTER_FLAG_CHGHDRS) + +/* + * Rspamd supports just version 6 of the protocol, failing all versions below + * this one + */ +#define RSPAMD_MILTER_PROTO_VER 6 + +#define RSPAMD_MILTER_MESSAGE_CHUNK 65536 + #endif