#include "file_mime_config.h"
-#include <sys/types.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
+#include "snort_types.h"
+
#include "file_api.h"
-#include "main/snort_types.h"
-#include "utils/sf_email_attach_decode.h"
-#include "utils/util.h"
-#include "parser/parser.h"
+#include "file_mime_process.h"
-#define CONF_SEPARATORS " \t\n\r"
-#define CONF_MAX_MIME_MEM "max_mime_mem"
-#define CONF_B64_DECODE "b64_decode_depth"
-#define CONF_QP_DECODE "qp_decode_depth"
-#define CONF_BITENC_DECODE "bitenc_decode_depth"
-#define CONF_UU_DECODE "uu_decode_depth"
-
-/*These are temporary values*/
-#define DEFAULT_MAX_MIME_MEM 838860
-#define DEFAULT_MIME_MEMCAP 838860
-#define DEFAULT_DEPTH 1464
-#define MAX_LOG_MEMCAP 104857600
-#define MIN_LOG_MEMCAP 3276
-#define MAX_MIME_MEM 104857600
-#define MIN_MIME_MEM 3276
-#define MAX_DEPTH 65535
-#define MIN_DEPTH -1
-
-#define ERRSTRLEN 512
-
-static int ProcessDecodeDepth(
- DecodeConfig* config, char* ErrorString, int ErrStrLen,
- const char* decode_type, DecodeType type, const char* preproc_name)
+void DecodeConfig::update_max_depth(int64_t depth)
{
- char* endptr;
- char* value;
- int decode_depth = 0;
- if (config == NULL)
- {
- snprintf(ErrorString, ErrStrLen, "%s config is NULL.\n", preproc_name);
- return -1;
- }
+ // 0 means unlimited
+ if (!depth)
+ max_depth = MAX_DEPTH;
+ else if (max_depth < depth)
+ max_depth = depth;
+}
- value = get_tok(NULL, CONF_SEPARATORS);
- if ( value == NULL )
- {
- snprintf(ErrorString, ErrStrLen,
- "Invalid format for %s config option '%s'.", preproc_name, decode_type);
- return -1;
- }
- decode_depth = strtol(value, &endptr, 10);
+void DecodeConfig::set_ignore_data(bool ignored)
+{
+ ignore_data = ignored;
+}
- if (*endptr)
- {
- snprintf(ErrorString, ErrStrLen,
- "Invalid format for %s config option '%s'.", preproc_name, decode_type);
- return -1;
- }
- if (decode_depth < MIN_DEPTH || decode_depth > MAX_DEPTH)
- {
- snprintf(ErrorString, ErrStrLen,
- "Invalid value for %s config option '%s'."
- "It should range between %d and %d.",
- preproc_name, decode_type, MIN_DEPTH, MAX_DEPTH);
- return -1;
- }
+bool DecodeConfig::is_ignore_data()
+{
+ return ignore_data;
+}
- switch (type)
- {
- case DECODE_B64:
- if ((decode_depth > 0) && (decode_depth & 3))
- {
- decode_depth += 4 - (decode_depth & 3);
- if (decode_depth > MAX_DEPTH )
- {
- decode_depth = decode_depth - 4;
- }
- ParseWarning(WARN_CONF,
- "%s: 'b64_decode_depth' is not a multiple of 4. "
- "Rounding up to the next multiple of 4. The new 'b64_decode_depth' is %d.\n",
- preproc_name, decode_depth);
- }
- config->b64_depth = decode_depth;
- break;
- case DECODE_QP:
- config->qp_depth = decode_depth;
- break;
- case DECODE_UU:
- config->uu_depth = decode_depth;
- break;
- case DECODE_BITENC:
- config->bitenc_depth = decode_depth;
- break;
- default:
- return -1;
- }
+void DecodeConfig::set_max_mime_mem(int max)
+{
+ max_mime_mem = max;
+}
- return 0;
+int DecodeConfig::get_max_mime_mem()
+{
+ return max_mime_mem;
}
-void set_mime_decode_config_defauts(DecodeConfig* decode_conf)
+void DecodeConfig::set_b64_depth(int depth)
{
- decode_conf->ignore_data = false;
- decode_conf->max_mime_mem = DEFAULT_MIME_MEMCAP;
- decode_conf->b64_depth = DEFAULT_DEPTH;
- decode_conf->qp_depth = DEFAULT_DEPTH;
- decode_conf->uu_depth = DEFAULT_DEPTH;
- decode_conf->bitenc_depth = DEFAULT_DEPTH;
- decode_conf->max_depth = DEFAULT_DEPTH;
+ b64_depth = depth;
+ update_max_depth(depth);
}
-void set_mime_log_config_defauts(MAIL_LogConfig* log_config)
+int DecodeConfig::get_b64_depth()
{
- log_config->memcap = DEFAULT_MIME_MEMCAP;
- log_config->log_filename = 0;
- log_config->log_mailfrom = 0;
- log_config->log_rcptto = 0;
- log_config->log_email_hdrs = 0;
- log_config->email_hdrs_log_depth = 0;
+ return b64_depth;
}
-bool is_decoding_enabled(DecodeConfig* decode_conf)
+void DecodeConfig::set_qp_depth(int depth)
{
- if ( (decode_conf->b64_depth > -1) || (decode_conf->qp_depth > -1)
- || (decode_conf->uu_depth > -1) || (decode_conf->bitenc_depth > -1)
- || (decode_conf->file_depth > -1))
- {
- return true;
- }
- else
- return false;
+ qp_depth = depth;
+ update_max_depth(depth);
}
-bool is_mime_log_enabled(MAIL_LogConfig* log_config)
+int DecodeConfig::get_qp_depth()
{
- if (log_config->log_email_hdrs || log_config->log_filename ||
- log_config->log_mailfrom || log_config->log_rcptto)
- return true;
- return false;
+ return qp_depth;
}
-bool is_decoding_conf_changed(DecodeConfig* configNext, DecodeConfig* config, const
- char* preproc_name)
+void DecodeConfig::set_bitenc_depth(int depth)
{
- if (configNext == NULL)
- {
- ErrorMessage("%s reload: Changing the %s configuration requires a restart.\n",
- preproc_name, preproc_name);
- return true;
- }
- if (configNext->max_mime_mem != config->max_mime_mem)
- {
- ErrorMessage("%s reload: Changing the memcap requires a restart.\n", preproc_name);
+ bitenc_depth = depth;
+ update_max_depth(depth);
+}
- return true;
- }
- if (configNext->b64_depth != config->b64_depth)
- {
- ErrorMessage("%s reload: Changing the b64_decode_depth requires a restart.\n",
- preproc_name);
+int DecodeConfig::get_bitenc_depth()
+{
+ return bitenc_depth;
+}
- return true;
- }
- if (configNext->qp_depth != config->qp_depth)
- {
- ErrorMessage("%s reload: Changing the qp_decode_depth requires a restart.\n",
- preproc_name);
+void DecodeConfig::set_uu_depth(int depth)
+{
+ uu_depth = depth;
+ update_max_depth(depth);
+}
- return true;
- }
- if (configNext->bitenc_depth != config->bitenc_depth)
- {
- ErrorMessage("%s reload: Changing the bitenc_decode_depth requires a restart.\n",
- preproc_name);
+int DecodeConfig::get_uu_depth()
+{
+ return uu_depth;
+}
- return true;
- }
- if (configNext->uu_depth != config->uu_depth)
- {
- ErrorMessage("%s reload: Changing the uu_decode_depth requires a restart.\n",
- preproc_name);
+int64_t DecodeConfig::get_file_depth()
+{
+ return file_depth;
+}
- return true;
- }
- if (configNext->file_depth != config->file_depth)
- {
- ErrorMessage("%s reload: Changing the file_depth requires a restart.\n", preproc_name);
+int DecodeConfig::get_max_depth()
+{
+ return max_depth;
+}
+bool DecodeConfig::is_decoding_enabled()
+{
+ if (max_depth > -1)
return true;
- }
- return false;
+ else
+ return false;
}
-/*
- *
- * Purpose: Process the configuration
- *
- * Arguments: args => argument list
- *
- * Returns: -1: error or not found
- * 0: no error
- *
- */
-int parse_mime_decode_args(DecodeConfig* decode_conf, char* arg, const char* preproc_name)
+void DecodeConfig::set_file_depth(int64_t file_depth)
{
- int ret = 0;
- char errStr[ERRSTRLEN];
- int errStrLen = ERRSTRLEN;
- unsigned long value = 0;
-
- if ((decode_conf == NULL) || (arg == NULL))
- return 0;
-
- *errStr = '\0';
-
- if ( !strcasecmp(CONF_MAX_MIME_MEM, arg) )
- {
- ret = CheckValueInRange(get_tok(NULL, CONF_SEPARATORS), CONF_MAX_MIME_MEM,
- MIN_MIME_MEM, MAX_MIME_MEM, &value);
- decode_conf->max_mime_mem = (int)value;
- }
- else if ( !strcasecmp(CONF_B64_DECODE, arg) )
+ if ((!file_depth) || (file_depth > MAX_DEPTH))
{
- ret = ProcessDecodeDepth(decode_conf, errStr, errStrLen, CONF_B64_DECODE, DECODE_B64,
- preproc_name);
+ max_depth = MAX_DEPTH;
}
- else if ( !strcasecmp(CONF_QP_DECODE, arg) )
+ else if (file_depth > max_depth)
{
- ret = ProcessDecodeDepth(decode_conf, errStr, errStrLen, CONF_QP_DECODE, DECODE_QP,
- preproc_name);
+ max_depth = (int)file_depth;
}
- else if ( !strcasecmp(CONF_UU_DECODE, arg) )
- {
- ret = ProcessDecodeDepth(decode_conf, errStr, errStrLen, CONF_UU_DECODE, DECODE_UU,
- preproc_name);
- }
- else if ( !strcasecmp(CONF_BITENC_DECODE, arg) )
- {
- ret = ProcessDecodeDepth(decode_conf, errStr, errStrLen, CONF_BITENC_DECODE, DECODE_BITENC,
- preproc_name);
- }
- else
- {
- return -1;
- }
-
- if (ret == -1)
- {
- /*
- ** Fatal Error, log error and exit.
- */
- if ( *errStr )
- ParseError("mime decode: %s", errStr);
- else
- ParseError("mime decode: %s", "undefined error");
- }
-
- return ret;
}
-
-void check_decode_config(DecodeConfig* currentConfig)
+// update file depth and max_depth etc
+void DecodeConfig::sync_all_depths()
{
- int max = -1;
-
- if (!currentConfig->max_mime_mem)
- currentConfig->max_mime_mem = DEFAULT_MAX_MIME_MEM;
+ file_depth = file_api->get_max_file_depth();
- if (!currentConfig->b64_depth || !currentConfig->qp_depth
- || !currentConfig->uu_depth || !currentConfig->bitenc_depth)
- {
- currentConfig->max_depth = MAX_DEPTH;
- }
- else
- {
- if (max < currentConfig->b64_depth)
- max = currentConfig->b64_depth;
-
- if (max < currentConfig->qp_depth)
- max = currentConfig->qp_depth;
-
- if (max < currentConfig->bitenc_depth)
- max = currentConfig->bitenc_depth;
-
- if (max < currentConfig->uu_depth)
- max = currentConfig->uu_depth;
-
- currentConfig->max_depth = max;
- }
+ set_file_depth(file_depth);
}