]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Add basic sanity checks for milter protocol
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 May 2017 16:18:09 +0000 (17:18 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 5 May 2017 17:02:07 +0000 (18:02 +0100)
src/libserver/milter.c
src/rspamd_proxy.c

index ae81a323f788ccb524a9f7bf5d458de615f5d733..14068e71b66d05955b34c75371a0ab2b0adbc108 100644 (file)
@@ -594,6 +594,33 @@ rspamd_milter_process_command (struct rspamd_milter_session *session,
        return TRUE;
 }
 
+static gboolean
+rspamd_milter_is_valid_cmd (guchar c)
+{
+       switch (c) {
+       case RSPAMD_MILTER_CMD_ABORT:
+       case RSPAMD_MILTER_CMD_BODY:
+       case RSPAMD_MILTER_CMD_CONNECT:
+       case RSPAMD_MILTER_CMD_MACRO:
+       case RSPAMD_MILTER_CMD_BODYEOB:
+       case RSPAMD_MILTER_CMD_HELO:
+       case RSPAMD_MILTER_CMD_QUIT_NC:
+       case RSPAMD_MILTER_CMD_HEADER:
+       case RSPAMD_MILTER_CMD_MAIL:
+       case RSPAMD_MILTER_CMD_EOH:
+       case RSPAMD_MILTER_CMD_OPTNEG:
+       case RSPAMD_MILTER_CMD_QUIT:
+       case RSPAMD_MILTER_CMD_RCPT:
+       case RSPAMD_MILTER_CMD_DATA:
+       case RSPAMD_MILTER_CMD_UNKNOWN:
+               return TRUE;
+       default:
+               break;
+       }
+
+       return FALSE;
+}
+
 static gboolean
 rspamd_milter_consume_input (struct rspamd_milter_session *session,
                struct rspamd_milter_private *priv)
@@ -651,6 +678,23 @@ rspamd_milter_consume_input (struct rspamd_milter_session *session,
                        break;
                case st_read_data:
                        /* We might need some more data in buffer for further steps */
+                       if (priv->parser.datalen == 0 || priv->parser.datalen >
+                                       RSPAMD_MILTER_MESSAGE_CHUNK * 2) {
+                               err = g_error_new (rspamd_milter_quark (), E2BIG,
+                                               "Command length is too big: %zd",
+                                               priv->parser.datalen);
+                               rspamd_milter_on_protocol_error (session, priv, err);
+
+                               return FALSE;
+                       }
+                       if (!rspamd_milter_is_valid_cmd (priv->parser.cur_cmd)) {
+                               err = g_error_new (rspamd_milter_quark (), E2BIG,
+                                               "Unvalid command: %c",
+                                               priv->parser.cur_cmd);
+                               rspamd_milter_on_protocol_error (session, priv, err);
+
+                               return FALSE;
+                       }
                        if (priv->parser.buf->allocated < priv->parser.datalen) {
                                priv->parser.buf = rspamd_fstring_grow (priv->parser.buf,
                                                priv->parser.pos + priv->parser.datalen);
index da34c0ca480ca00cad30b5b049e1a187e8d50c09..a0544650d1d298f91d3ab65d42273bcb648b6788 100644 (file)
@@ -1620,13 +1620,14 @@ proxy_accept_socket (gint fd, short what, void *arg)
                                ctx->ev_base);
        }
        else {
+               msg_info_session ("accepted milter connection from %s port %d",
+                               rspamd_inet_address_to_string (addr),
+                               rspamd_inet_address_get_port (addr));
+
                rspamd_milter_handle_socket (nfd, &ctx->io_tv, ctx->ev_base,
                                proxy_milter_finish_handler,
                                proxy_milter_error_handler,
                                session);
-               msg_info_session ("accepted milter connection from %s port %d",
-                               rspamd_inet_address_to_string (addr),
-                               rspamd_inet_address_get_port (addr));
        }
 }