/* Parses and processes the configuration arguments * supplied in the DNS preprocessor rule. * * PARAMETERS: * * argp: Pointer to string containing the config arguments. * * RETURNS: Nothing. */ static void ParseDNSArgs( u_char* argp ) { char* cur_tokenp = NULL; char* argcpyp = NULL; int port; /* Set up default port to listen on */ dns_config.ports[ PORT_INDEX( DNS_PORT ) ] |= CONV_PORT(DNS_PORT); /* Sanity check(s) */ if ( !argp ) { PrintDNSConfig(); return; } argcpyp = strdup( (char*) argp ); if ( !argcpyp ) { DynamicPreprocessorFatalMessage("Could not allocate memory to parse DNS options.\n"); return; } cur_tokenp = strtok( argcpyp, " "); while ( cur_tokenp ) { if ( !strcmp( cur_tokenp, DNS_PORTS_KEYWORD )) { /* If the user specified ports, remove 'DNS_PORT' for now since * it now needs to be set explicitely. */ dns_config.ports[ PORT_INDEX( DNS_PORT ) ] = 0; /* Eat the open brace. */ cur_tokenp = strtok( NULL, " "); if (( !cur_tokenp ) || ( strcmp(cur_tokenp, "{" ))) { DynamicPreprocessorFatalMessage("%s(%d) Bad value specified for %s. Must start " "with '{' and be space seperated.\n", *(_dpd.config_file), *(_dpd.config_line), DNS_PORTS_KEYWORD); free(argcpyp); return; } cur_tokenp = strtok( NULL, " "); while (( cur_tokenp ) && strcmp(cur_tokenp, "}" )) { if ( !isdigit( cur_tokenp[0] )) { DynamicPreprocessorFatalMessage("%s(%d) Bad port %s.\n", *(_dpd.config_file), *(_dpd.config_line), cur_tokenp ); free(argcpyp); return; } else { port = atoi( cur_tokenp ); if( port < 0 || port > MAX_PORTS ) { DynamicPreprocessorFatalMessage("%s(%d) Port value illegitimate: %s\n", *(_dpd.config_file), *(_dpd.config_line), cur_tokenp ); free(argcpyp); return; } dns_config.ports[ PORT_INDEX( port ) ] |= CONV_PORT(port); } cur_tokenp = strtok( NULL, " "); } } else if ( !strcmp( cur_tokenp, DNS_ENABLE_RDATA_OVERFLOW_KEYWORD )) { dns_config.enabled_alerts |= DNS_ALERT_RDATA_OVERFLOW; } else if ( !strcmp( cur_tokenp, DNS_ENABLE_OBSOLETE_TYPES_KEYWORD )) { dns_config.enabled_alerts |= DNS_ALERT_OBSOLETE_TYPES; } else if ( !strcmp( cur_tokenp, DNS_ENABLE_EXPERIMENTAL_TYPES_KEYWORD )) { dns_config.enabled_alerts |= DNS_ALERT_EXPERIMENTAL_TYPES; } #if 0 else if ( !strcmp( cur_tokenp, DNS_AUTODETECT_KEYWORD )) { dns_config.autodetect++; } #endif else { DynamicPreprocessorFatalMessage("Invalid argument: %s\n", cur_tokenp); return; } cur_tokenp = strtok( NULL, " " ); } PrintDNSConfig(); free(argcpyp); }
/* Initializes the SSH preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config * data. * * RETURNS: Nothing. */ static void SSHInit(char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(); SSHConfig *pPolicyConfig = NULL; if (ssh_config == NULL) { //create a context ssh_config = sfPolicyConfigCreate(); if (ssh_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SSH config.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupSSH(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreprocConfCheck(SSHCheckConfig); _dpd.addPreprocExit(SSHCleanExit, NULL, PRIORITY_LAST, PP_SSH); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ssh", (void *)&sshPerfStats, 0, _dpd.totalPerfStats); #endif #ifdef TARGET_BASED ssh_app_id = _dpd.findProtocolReference("ssh"); if (ssh_app_id == SFTARGET_UNKNOWN_PROTOCOL) ssh_app_id = _dpd.addProtocolReference("ssh"); #endif } sfPolicyUserPolicySet (ssh_config, policy_id); pPolicyConfig = (SSHConfig *)sfPolicyUserDataGetCurrent(ssh_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSH preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSHConfig *)calloc(1, sizeof(SSHConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SSH preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssh_config, pPolicyConfig); ParseSSHArgs(pPolicyConfig, (u_char *)argp); _dpd.addPreproc( ProcessSSH, PRIORITY_APPLICATION, PP_SSH, PROTO_BIT__TCP ); _addPortsToStream5Filter(pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(policy_id); #endif }
static int AddCmd(char *name) { static int num_cmds = CMD_LAST + 1; static int id = CMD_LAST; SMTPToken *cmds, *tmp_cmds; SMTPSearch *cmd_search; SMTPCmdConfig *cmd_config; int ret; /* allocate enough memory for new commmand - alloc one extra for NULL entry */ cmds = (SMTPToken *)calloc(num_cmds + 1, sizeof(SMTPToken)); if (cmds == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_search = (SMTPSearch *)calloc(num_cmds, sizeof(SMTPSearch)); if (cmd_search == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_config = (SMTPCmdConfig *)calloc(num_cmds, sizeof(SMTPCmdConfig)); if (cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* copy existing commands into newly allocated memory * don't need to copy anything from cmd_search since this hasn't been initialized yet */ ret = SafeMemcpy(cmds, _smtp_cmds, id * sizeof(SMTPToken), cmds, cmds + num_cmds); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } ret = SafeMemcpy(cmd_config, _smtp_cmd_config, id * sizeof(SMTPCmdConfig), cmd_config, cmd_config + num_cmds); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* add new command to cmds * cmd_config doesn't need anything added - this will probably be done by a calling function * cmd_search will be initialized when the searches are initialized */ tmp_cmds = &cmds[id]; tmp_cmds->name = strdup(name); tmp_cmds->name_len = strlen(name); tmp_cmds->search_id = id; if (tmp_cmds->name == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* free global memory structures */ if (_smtp_cmds != NULL) free(_smtp_cmds); if (_smtp_cmd_search != NULL) free(_smtp_cmd_search); if (_smtp_cmd_config != NULL) free(_smtp_cmd_config); /* set globals to new memory */ _smtp_cmds = cmds; _smtp_cmd_search = cmd_search; _smtp_cmd_config = cmd_config; ret = id; id++; num_cmds++; return ret; }
static void ParseDNP3Args(struct _SnortConfig *sc, dnp3_config_t *config, char *args) { char *saveptr; char *token; /* Set defaults */ config->memcap = DNP3_DEFAULT_MEMCAP; config->ports[PORT_INDEX(DNP3_PORT)] |= CONV_PORT(DNP3_PORT); config->check_crc = 0; /* No arguments? Stick with defaults. */ if (args == NULL) return; token = strtok_r(args, " ,", &saveptr); while (token != NULL) { if (strcmp(token, DNP3_PORTS_KEYWORD) == 0) { unsigned nPorts = 0; /* Un-set the default port */ config->ports[PORT_INDEX(DNP3_PORT)] = 0; /* Parse ports */ token = strtok_r(NULL, " ,", &saveptr); if (token == NULL) { DynamicPreprocessorFatalMessage("%s(%d): Missing argument for " "DNP3 preprocessor 'ports' option.\n", *_dpd.config_file, *_dpd.config_line); } if (isdigit(token[0])) { ParseSinglePort(config, token); nPorts++; } else if (*token == '{') { /* list of ports */ token = strtok_r(NULL, " ,", &saveptr); while (token != NULL && *token != '}') { ParseSinglePort(config, token); nPorts++; token = strtok_r(NULL, " ,", &saveptr); } } else { nPorts = 0; } if ( nPorts == 0 ) { DynamicPreprocessorFatalMessage("%s(%d): Bad DNP3 'ports' argument: '%s'\n" "Argument to DNP3 'ports' must be an integer, or a list " "enclosed in { } braces.\n", *_dpd.config_file, *_dpd.config_line, token); } } else if (strcmp(token, DNP3_MEMCAP_KEYWORD) == 0) { uint32_t memcap; char *endptr; /* Parse memcap */ token = strtok_r(NULL, " ", &saveptr); /* In a multiple policy scenario, the memcap from the default policy overrides the memcap in any targeted policies. */ if (_dpd.getParserPolicy(sc) != _dpd.getDefaultPolicy()) { dnp3_config_t *default_config = (dnp3_config_t *)sfPolicyUserDataGet(dnp3_context_id, _dpd.getDefaultPolicy()); if (!default_config || default_config->memcap == 0) { DynamicPreprocessorFatalMessage("%s(%d): DNP3 'memcap' must be " "configured in the default config.\n", *_dpd.config_file, *_dpd.config_line); } config->memcap = default_config->memcap; } else { if (token == NULL) { DynamicPreprocessorFatalMessage("%s(%d): Missing argument for DNP3 " "preprocessor 'memcap' option.\n", *_dpd.config_file, *_dpd.config_line); } memcap = _dpd.SnortStrtoul(token, &endptr, 10); if ((token[0] == '-') || (*endptr != '\0') || (memcap < MIN_DNP3_MEMCAP) || (memcap > MAX_DNP3_MEMCAP)) { DynamicPreprocessorFatalMessage("%s(%d): Bad DNP3 'memcap' argument: %s\n" "Argument to DNP3 'memcap' must be an integer between " "%d and %d.\n", *_dpd.config_file, *_dpd.config_line, token, MIN_DNP3_MEMCAP, MAX_DNP3_MEMCAP); } config->memcap = memcap; } } else if (strcmp(token, DNP3_CHECK_CRC_KEYWORD) == 0) { /* Parse check_crc */ config->check_crc = 1; } else if (strcmp(token, DNP3_DISABLED_KEYWORD) == 0) { /* TODO: if disabled, check that no other stuff is turned on except memcap */ config->disabled = 1; } else { DynamicPreprocessorFatalMessage("%s(%d): Failed to parse dnp3 argument: " "%s\n", *_dpd.config_file, *_dpd.config_line, token); } token = strtok_r(NULL, " ,", &saveptr); } }
void IMAP_CheckConfig(IMAPConfig *pPolicyConfig, tSfPolicyUserContextId context) { int max = -1; IMAPConfig *defaultConfig = (IMAPConfig *)sfPolicyUserDataGetDefault(context); if (pPolicyConfig == defaultConfig) { if (!pPolicyConfig->memcap) pPolicyConfig->memcap = DEFAULT_IMAP_MEMCAP; if(!pPolicyConfig->b64_depth || !pPolicyConfig->qp_depth || !pPolicyConfig->uu_depth || !pPolicyConfig->bitenc_depth) { pPolicyConfig->max_depth = MAX_DEPTH; return; } else { if(max < pPolicyConfig->b64_depth) max = pPolicyConfig->b64_depth; if(max < pPolicyConfig->qp_depth) max = pPolicyConfig->qp_depth; if(max < pPolicyConfig->bitenc_depth) max = pPolicyConfig->bitenc_depth; if(max < pPolicyConfig->uu_depth) max = pPolicyConfig->uu_depth; pPolicyConfig->max_depth = max; } } else if (defaultConfig == NULL) { if (pPolicyConfig->memcap) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: memcap must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->b64_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: b64_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->qp_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: qp_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->uu_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: uu_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->bitenc_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: bitenc_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } } else { pPolicyConfig->memcap = defaultConfig->memcap; pPolicyConfig->max_depth = defaultConfig->max_depth; if(pPolicyConfig->disabled) { pPolicyConfig->b64_depth = defaultConfig->b64_depth; pPolicyConfig->qp_depth = defaultConfig->qp_depth; pPolicyConfig->uu_depth = defaultConfig->uu_depth; pPolicyConfig->bitenc_depth = defaultConfig->bitenc_depth; return; } if(!pPolicyConfig->b64_depth && defaultConfig->b64_depth) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: Cannot enable unlimited Base64 decoding" " in non-default config without turning on unlimited Base64 decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->b64_depth && (pPolicyConfig->b64_depth > defaultConfig->b64_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: b64_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->b64_depth, defaultConfig->b64_depth); } if(!pPolicyConfig->qp_depth && defaultConfig->qp_depth) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: Cannot enable unlimited Quoted-Printable decoding" " in non-default config without turning on unlimited Quoted-Printable decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->qp_depth && (pPolicyConfig->qp_depth > defaultConfig->qp_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: qp_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->qp_depth, defaultConfig->qp_depth); } if(!pPolicyConfig->uu_depth && defaultConfig->uu_depth ) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: Cannot enable unlimited Unix-to-Unix decoding" " in non-default config without turning on unlimited Unix-to-Unix decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->uu_depth && (pPolicyConfig->uu_depth > defaultConfig->uu_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: uu_decode_depth value %d in the non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line),pPolicyConfig->uu_depth, defaultConfig->uu_depth); } if(!pPolicyConfig->bitenc_depth && defaultConfig->bitenc_depth) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: Cannot enable unlimited 7bit/8bit/binary extraction" " in non-default config without turning on unlimited 7bit/8bit/binary extraction in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->bitenc_depth && (pPolicyConfig->bitenc_depth > defaultConfig->bitenc_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => IMAP: bitenc_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->bitenc_depth, defaultConfig->bitenc_depth); } } }
/* Initializes the GTP preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config data. * * RETURNS: Nothing. */ static void GTPInit(struct _SnortConfig *sc, char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); GTPConfig *pDefaultPolicyConfig = NULL; GTPConfig *pPolicyConfig = NULL; if (gtp_config == NULL) { /*create a context*/ gtp_config = sfPolicyConfigCreate(); if (gtp_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for GTP config.\n"); } _dpd.addPreprocConfCheck(sc, GTPCheckConfig); _dpd.registerPreprocStats(GTP_NAME, GTP_PrintStats); _dpd.addPreprocExit(GTPCleanExit, NULL, PRIORITY_LAST, PP_GTP); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("gtp", (void *)>pPerfStats, 0, _dpd.totalPerfStats, NULL); #endif #ifdef TARGET_BASED gtp_app_id = _dpd.findProtocolReference("gtp"); if (gtp_app_id == SFTARGET_UNKNOWN_PROTOCOL) gtp_app_id = _dpd.addProtocolReference("gtp"); // register with session to handle applications _dpd.sessionAPI->register_service_handler( PP_GTP, gtp_app_id ); #endif } sfPolicyUserPolicySet (gtp_config, policy_id); pDefaultPolicyConfig = (GTPConfig *)sfPolicyUserDataGetDefault(gtp_config); pPolicyConfig = (GTPConfig *)sfPolicyUserDataGetCurrent(gtp_config); if ((pPolicyConfig != NULL) && (pDefaultPolicyConfig == NULL)) { DynamicPreprocessorFatalMessage("GTP preprocessor can only be " "configured once.\n"); } pPolicyConfig = (GTPConfig *)calloc(1, sizeof(GTPConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "GTP preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(gtp_config, pPolicyConfig); GTP_RegRuleOptions(sc); ParseGTPArgs(pPolicyConfig, (u_char *)argp); if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupGTP(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreproc( sc, GTPmain, PRIORITY_APPLICATION, PP_GTP, PROTO_BIT__UDP ); // register ports with session and stream registerPortsForDispatch( sc, pPolicyConfig ); registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); _addPortsToStreamFilter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStreamFilter(sc, policy_id); #endif }
static int AddCmd(SMTPConfig *config, char *name) { SMTPToken *cmds, *tmp_cmds; SMTPSearch *cmd_search; SMTPCmdConfig *cmd_config; int ret; if (config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) SMTP config is NULL.\n", __FILE__, __LINE__); } config->num_cmds++; /* allocate enough memory for new commmand - alloc one extra for NULL entry */ cmds = (SMTPToken *)calloc(config->num_cmds + 1, sizeof(SMTPToken)); if (cmds == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* This gets filled in later */ cmd_search = (SMTPSearch *)calloc(config->num_cmds, sizeof(SMTPSearch)); if (cmd_search == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } cmd_config = (SMTPCmdConfig *)calloc(config->num_cmds, sizeof(SMTPCmdConfig)); if (cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* copy existing commands into newly allocated memory * don't need to copy anything from cmd_search since this hasn't been initialized yet */ ret = SafeMemcpy(cmds, config->cmds, (config->num_cmds - 1) * sizeof(SMTPToken), cmds, cmds + (config->num_cmds - 1)); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } ret = SafeMemcpy(cmd_config, config->cmd_config, (config->num_cmds - 1) * sizeof(SMTPCmdConfig), cmd_config, cmd_config + (config->num_cmds - 1)); if (ret != SAFEMEM_SUCCESS) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to memory copy SMTP command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* add new command to cmds * cmd_config doesn't need anything added - this will probably be done by a calling function * cmd_search will be initialized when the searches are initialized */ tmp_cmds = &cmds[config->num_cmds - 1]; tmp_cmds->name = strdup(name); tmp_cmds->name_len = strlen(name); tmp_cmds->search_id = config->num_cmds - 1; if (tmp_cmds->name == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } /* free global memory structures */ if (config->cmds != NULL) free(config->cmds); if (config->cmd_search != NULL) free(config->cmd_search); if (config->cmd_config != NULL) free(config->cmd_config); /* set globals to new memory */ config->cmds = cmds; config->cmd_search = cmd_search; config->cmd_config = cmd_config; return (config->num_cmds - 1); }
void SSLPP_init(struct _SnortConfig *sc, char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SSLPP_config_t *pPolicyConfig = NULL; if (ssl_config == NULL) { //create a context ssl_config = sfPolicyConfigCreate(); if (ssl_config == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage( "SSLPP_init(): The Stream preprocessor must be enabled.\n"); } SSL_InitGlobals(); _dpd.registerPreprocStats("ssl", SSLPP_drop_stats); _dpd.addPreprocConfCheck(sc, SSLPP_CheckConfig); _dpd.addPreprocExit(SSLCleanExit, NULL, PRIORITY_LAST, PP_SSL); _dpd.addPreprocResetStats(SSLResetStats, NULL, PRIORITY_LAST, PP_SSL); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ssl", (void *)&sslpp_perf_stats, 0, _dpd.totalPerfStats); #endif #ifdef ENABLE_HA _dpd.addFuncToPostConfigList(sc, SSLHAPostConfigInit, NULL); #endif #ifdef TARGET_BASED ssl_app_id = _dpd.findProtocolReference("ssl"); if (ssl_app_id == SFTARGET_UNKNOWN_PROTOCOL) { ssl_app_id = _dpd.addProtocolReference("ssl"); } _dpd.sessionAPI->register_service_handler( PP_SSL, ssl_app_id ); #endif } sfPolicyUserPolicySet (ssl_config, policy_id); pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSL preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t)); if (pPolicyConfig == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssl_config, pPolicyConfig); SSLPP_init_config(pPolicyConfig); SSLPP_config(pPolicyConfig, args); SSLPP_print_config(pPolicyConfig); _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.addPreproc( sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP ); registerPortsForDispatch( sc, pPolicyConfig ); registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); _addPortsToStream5Filter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(sc, policy_id); #endif }
void SSLReload(struct _SnortConfig *sc, char *args, void **new_config) { tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)*new_config; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SSLPP_config_t * pPolicyConfig = NULL; if (ssl_swap_config == NULL) { //create a context ssl_swap_config = sfPolicyConfigCreate(); if (ssl_swap_config == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage( "SSLPP_init(): The Stream preprocessor must be enabled.\n"); } *new_config = (void *)ssl_swap_config; } sfPolicyUserPolicySet (ssl_swap_config, policy_id); pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSL preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t)); if (pPolicyConfig == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssl_swap_config, pPolicyConfig); SSLPP_init_config(pPolicyConfig); SSLPP_config(pPolicyConfig, args); SSLPP_print_config(pPolicyConfig); _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.addPreproc(sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP); registerPortsForDispatch( sc, pPolicyConfig ); registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); _addPortsToStream5Filter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(sc, policy_id); #endif }
/* SSL Preprocessor configuration parsing */ static void SSLPP_config(SSLPP_config_t *config, char *conf) { char *saveptr; char *space_tok; char *comma_tok; char *portptr; char *search; SFP_errstr_t err; if(!conf) return; if (config == NULL) return; search = conf; while( (comma_tok = strtok_r(search, ",", &saveptr)) != NULL ) { search = NULL; space_tok = strtok_r(comma_tok, " ", &portptr); if(!space_tok) return; if(!strcasecmp(space_tok, "ports")) { memset(config->ports, 0, sizeof(config->ports)); if(SFP_ports(config->ports, portptr, err) != SFP_SUCCESS) DynamicPreprocessorFatalMessage( "%s(%d) => Failed to parse: %s\n", *(_dpd.config_file), *(_dpd.config_line), SFP_GET_ERR(err)); } else if(!strcasecmp(space_tok, "noinspect_encrypted")) { char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the" " SSL preprocessor: '%s' in %s\n", *(_dpd.config_file), *(_dpd.config_line), space_tok, tmpChar); } config->flags |= SSLPP_DISABLE_FLAG; } else if(!strcasecmp(space_tok, "trustservers")) { char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the" " SSL preprocessor: '%s' in %s\n", *(_dpd.config_file), *(_dpd.config_line), space_tok, tmpChar); } config->flags |= SSLPP_TRUSTSERVER_FLAG; } else if(!strcasecmp(space_tok, "pki_dir")) { char *tmpChar; char full_path_dirname[PATH_MAX+1]; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } UpdatePathToDir(full_path_dirname, PATH_MAX, tmpChar); config->pki_dir = strdup(full_path_dirname); } else if(!strcasecmp(space_tok, "ssl_rules_dir")) { char *tmpChar; char full_path_dirname[PATH_MAX+1]; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } UpdatePathToDir(full_path_dirname, PATH_MAX, tmpChar); config->ssl_rules_dir = strdup(full_path_dirname); } else if(!strcasecmp(space_tok, "memcap")) { int value; char *endStr = NULL; char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } value = _dpd.SnortStrtol( tmpChar, &endStr, 10); if (( *endStr) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } config->memcap = value; } else if(!strcasecmp(space_tok, "decrypt_memcap")) { int value; char *endStr = NULL; char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } value = _dpd.SnortStrtol( tmpChar, &endStr, 10); if (( *endStr) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } config->decrypt_memcap = value; } #ifdef ENABLE_HA else if(!strcasecmp(space_tok, "enable_ssl_ha")) { char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } if(!strcasecmp(tmpChar, "yes")) config->enable_ssl_ha = true; else if(!strcasecmp(tmpChar, "no")) config->enable_ssl_ha = false; else { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument '%s' to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), tmpChar, space_tok); } } #endif else if(!strcasecmp(space_tok, "max_heartbeat_length")) { int value; char *endStr = NULL; char *tmpChar; tmpChar = strtok_r(NULL, " \t\n", &portptr); if(tmpChar == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } value = _dpd.SnortStrtol( tmpChar, &endStr, 10); if (( *endStr) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the" " SSL preprocessor\n", *(_dpd.config_file), *(_dpd.config_line), space_tok); } if (value < MIN_HB_LEN || value > MAX_HB_LEN) { DynamicPreprocessorFatalMessage(" %s(%d) => Value specified for %s is out of " "bounds. Please specify an integer between %d and %d.\n", *(_dpd.config_file), *(_dpd.config_line), space_tok, MIN_HB_LEN, MAX_HB_LEN); } config->max_heartbeat_len = value; } else { DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the" " SSL preprocessor: '%s' in %s\n", *(_dpd.config_file), *(_dpd.config_line), comma_tok, conf); } } /* Verify configured options make sense */ if ((config->flags & SSLPP_TRUSTSERVER_FLAG) && !(config->flags & SSLPP_DISABLE_FLAG)) { DynamicPreprocessorFatalMessage("%s(%d) => SSL preprocessor: 'trustservers' " "requires 'noinspect_encrypted' to be useful.\n", *(_dpd.config_file), *(_dpd.config_line)); } }
/* Parsing for the ssl_state rule option */ static int SSLPP_state_init(struct _SnortConfig *sc, char *name, char *params, void **data) { int flags = 0, mask = 0; char *end = NULL; char *tok; SslRuleOptData *sdata; tok = strtok_r(params, ",", &end); if(!tok) DynamicPreprocessorFatalMessage("%s(%d) => missing argument to" "ssl_state keyword\n", *(_dpd.config_file), *(_dpd.config_line)); do { int negated = 0; if (tok[0] == '!') { negated = 1; tok++; } if(!strcasecmp("client_hello", tok)) { flags |= SSL_CUR_CLIENT_HELLO_FLAG; if (negated) mask |= SSL_CUR_CLIENT_HELLO_FLAG; } else if(!strcasecmp("server_hello", tok)) { flags |= SSL_CUR_SERVER_HELLO_FLAG; if (negated) mask |= SSL_CUR_SERVER_HELLO_FLAG; } else if(!strcasecmp("client_keyx", tok)) { flags |= SSL_CUR_CLIENT_KEYX_FLAG; if (negated) mask |= SSL_CUR_CLIENT_KEYX_FLAG; } else if(!strcasecmp("server_keyx", tok)) { flags |= SSL_CUR_SERVER_KEYX_FLAG; if (negated) mask |= SSL_CUR_SERVER_KEYX_FLAG; } else if(!strcasecmp("unknown", tok)) { flags |= SSL_UNKNOWN_FLAG; if (negated) mask |= SSL_UNKNOWN_FLAG; } else { DynamicPreprocessorFatalMessage( "%s(%d) => %s is not a recognized argument to %s.\n", *(_dpd.config_file), _dpd.config_file, tok, name); } } while( (tok = strtok_r(NULL, ",", &end)) != NULL ); sdata = (SslRuleOptData *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "ssl_state preprocessor rule option.\n"); } sdata->flags = flags; sdata->mask = mask; *data = (void *)sdata; return 1; }
static void UpdatePathToDir(char *full_path_dirname, unsigned int max_size, char *dirname) { int iRet; char *snort_conf_dir = *(_dpd.snort_conf_dir); if (!snort_conf_dir || !(*snort_conf_dir) || !full_path_dirname || !dirname) { DynamicPreprocessorFatalMessage(" %s(%d) => can't create path.\n", *(_dpd.config_file), *(_dpd.config_line)); } /*dirname is too long*/ if ( max_size < strlen(dirname) ) { DynamicPreprocessorFatalMessage(" %s(%d) => the dir name length %u is longer than allowed %u.\n", *(_dpd.config_file), *(_dpd.config_line), strlen(dirname), max_size); } /* * If an absolute path is specified, then use that. */ #ifndef WIN32 if(dirname[0] == '/') { iRet = snprintf(full_path_dirname, max_size, "%s", dirname); } else { /* * Set up the dir name directory. */ if (snort_conf_dir[strlen(snort_conf_dir) - 1] == '/') { iRet = snprintf(full_path_dirname,max_size, "%s%s", snort_conf_dir, dirname); } else { iRet = snprintf(full_path_dirname, max_size, "%s/%s", snort_conf_dir, dirname); } } #else if(strlen(dirname)>3 && dirname[1]==':' && dirname[2]=='\\') { iRet = snprintf(full_path_dirname, max_size, "%s", dirname); } else { /* ** Set up the dir name directory */ if (snort_conf_dir[strlen(snort_conf_dir) - 1] == '\\' || snort_conf_dir[strlen(snort_conf_dir) - 1] == '/' ) { iRet = snprintf(full_path_dirname,max_size, "%s%s", snort_conf_dir, dirname); } else { iRet = snprintf(full_path_dirname, max_size, "%s\\%s", snort_conf_dir, dirname); } } #endif if(iRet < 0) { DynamicPreprocessorFatalMessage(" %s(%d) => the dir name length %u is longer than allowed %u.\n", *(_dpd.config_file), *(_dpd.config_line), strlen(dirname), max_size); } }
/* Parsing for the ssl_version rule option */ static int SSLPP_ver_init(struct _SnortConfig *sc, char *name, char *params, void **data) { int flags = 0, mask = 0; char *end = NULL; char *tok; SslRuleOptData *sdata; tok = strtok_r(params, ",", &end); if(!tok) DynamicPreprocessorFatalMessage("%s(%d) => missing argument to" "ssl_state keyword\n", *(_dpd.config_file), *(_dpd.config_line)); do { int negated = 0; if (tok[0] == '!') { negated = 1; tok++; } if(!strcasecmp("sslv2", tok)) { flags |= SSL_VER_SSLV2_FLAG; if (negated) mask |= SSL_VER_SSLV2_FLAG; } else if(!strcasecmp("sslv3", tok)) { flags |= SSL_VER_SSLV3_FLAG; if (negated) mask |= SSL_VER_SSLV3_FLAG; } else if(!strcasecmp("tls1.0", tok)) { flags |= SSL_VER_TLS10_FLAG; if (negated) mask |= SSL_VER_TLS10_FLAG; } else if(!strcasecmp("tls1.1", tok)) { flags |= SSL_VER_TLS11_FLAG; if (negated) mask |= SSL_VER_TLS11_FLAG; } else if(!strcasecmp("tls1.2", tok)) { flags |= SSL_VER_TLS12_FLAG; if (negated) mask |= SSL_VER_TLS12_FLAG; } else { DynamicPreprocessorFatalMessage( "%s(%d) => %s is not a recognized argument to %s.\n", *(_dpd.config_file), _dpd.config_file, tok, name); } } while( (tok = strtok_r(NULL, ",", &end)) != NULL ); sdata = (SslRuleOptData *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "ssl_version preprocessor rule option.\n"); } sdata->flags = flags; sdata->mask = mask; *data = (void *)sdata; return 1; }
/* * Function: FTPStatefulSessionInspection(Packet *p, * FTPTELNET_GLOBAL_CONF *GlobalConf, * FTP_SESSION **FtpSession, * FTPP_SI_INPUT *SiInput, int *piInspectMode) * * Purpose: Initialize the session and server configurations for this * packet/stream. In this function, we set the Session pointer * (which includes the correct server configuration). The actual * processing to find which IP is the server and which is the * client, is done in the InitServerConf() function. * * Arguments: p => pointer to the Packet/Session * GlobalConf => pointer to the global configuration * Session => double pointer to the Session structure * SiInput => pointer to the session information * piInspectMode => pointer so the inspection mode can be set * * Returns: int => return code indicating error or success * */ static int FTPStatefulSessionInspection(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf, FTP_SESSION **FtpSession, FTPP_SI_INPUT *SiInput, int *piInspectMode) { FTP_CLIENT_PROTO_CONF *ClientConf; FTP_SERVER_PROTO_CONF *ServerConf; int iRet; FTP_SESSION *NewSession; /* * First, check if there is already a session pointer. */ if (p->stream_session_ptr) { *FtpSession = _dpd.streamAPI->get_application_data(p->stream_session_ptr, PP_FTPTELNET); if (*FtpSession) { if (SiInput->pdir != FTPP_SI_NO_MODE) { *piInspectMode = SiInput->pdir; } else { FTP_SESSION *tmp = *FtpSession; /* check session pointer server conf port */ if (tmp->server_conf && tmp->server_conf->proto_ports.ports[SiInput->sport]) *piInspectMode = FTPP_SI_SERVER_MODE; else if (tmp->server_conf && tmp->server_conf->proto_ports.ports[SiInput->dport]) *piInspectMode = FTPP_SI_CLIENT_MODE; else *piInspectMode = FTPGetPacketDir(p); } return FTPP_SUCCESS; } } /* * If not, create a new one, and initialize it. */ iRet = FTPInitConf(p, GlobalConf, &ClientConf, &ServerConf, SiInput, piInspectMode); if (iRet) { return iRet; } if (*piInspectMode) { NewSession = (FTP_SESSION *)calloc(1, sizeof(FTP_SESSION)); if (NewSession == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for new FTP session\n", *(_dpd.config_file), *(_dpd.config_line)); } FTPResetSession(NewSession, 1); NewSession->client_conf = ClientConf; NewSession->server_conf = ServerConf; NewSession->global_conf = GlobalConf; *FtpSession = NewSession; return FTPP_SUCCESS; } return FTPP_INVALID_PROTO; }
/* This function receives the OTN of a fully-parsed rule, checks that it is a SDF rule, then adds pattern & OTN to the SDF pattern-matching tree. */ int SDFOtnHandler(struct _SnortConfig *sc, void *potn) { OptTreeNode *otn = (OptTreeNode *)potn; SDFConfig *config; tSfPolicyId policy_id; SDFOptionData *sdf_data; OptFpList *tmp = otn->opt_func; PreprocessorOptionInfo *preproc_info = NULL; tSfPolicyUserContextId context_to_use = sdf_context->context_id; sdf_tree_node *head_node_to_use = sdf_context->head_node; uint32_t *num_patterns_to_use = &sdf_context->num_patterns; int sdf_option_added = 0; #ifdef SNORT_RELOAD /* If we are reloading, use that context instead. This should work since preprocessors get configured before rule parsing */ SDFContext *sdf_swap_context; sdf_swap_context = (SDFContext *)_dpd.getRelatedReloadData(sc, "sensitive_data"); if (sdf_swap_context != NULL) { context_to_use = sdf_swap_context->context_id; head_node_to_use = sdf_swap_context->head_node; num_patterns_to_use = &sdf_swap_context->num_patterns; } #endif /* Retrieve the current policy being parsed */ policy_id = _dpd.getParserPolicy(sc); sfPolicyUserPolicySet(context_to_use, policy_id); config = (SDFConfig *) sfPolicyUserDataGetCurrent(context_to_use); /* Check that this is a SDF rule, then grab the context data. */ while (tmp != NULL && tmp->type != RULE_OPTION_TYPE_LEAF_NODE) { if (tmp->type == RULE_OPTION_TYPE_PREPROCESSOR) preproc_info = tmp->context; if (preproc_info == NULL || preproc_info->optionEval != (PreprocOptionEval) SDFOptionEval) { DynamicPreprocessorFatalMessage("%s(%d) Rules with SDF options cannot " "have other detection options in the same rule.\n", *_dpd.config_file, *_dpd.config_line); } if (sdf_option_added) { DynamicPreprocessorFatalMessage("A rule may contain only one " "\"%s\" option.\n", SDF_OPTION_NAME); } if (otn->sigInfo.generator != GENERATOR_SPP_SDF_RULES) { DynamicPreprocessorFatalMessage("Rules with SDF options must " "use GID %d.\n", GENERATOR_SPP_SDF_RULES); } sdf_data = (SDFOptionData *)preproc_info->data; sdf_data->otn = otn; sdf_data->sid = otn->sigInfo.id; sdf_data->gid = otn->sigInfo.generator; /* Add the pattern to the SDF pattern-matching tree */ AddPii(head_node_to_use, sdf_data); sdf_data->counter_index = (*num_patterns_to_use)++; AddPortsToConf(sc, config, otn); AddProtocolsToConf(sc, config, otn); sdf_option_added = 1; preproc_info = NULL; tmp = tmp->next; } return 1; }
int ModbusFuncInit(struct _SnortConfig *sc, char *name, char *params, void **data) { char *endptr; modbus_option_data_t *modbus_data; unsigned int func_code = 0; if (name == NULL || data == NULL) return 0; if (strcmp(name, MODBUS_FUNC_NAME) != 0) return 0; if (params == NULL) { DynamicPreprocessorFatalMessage("%s(%d): No argument given for modbus_func. " "modbus_func requires a number between 0 and 255, or a valid function " "name.\n", *_dpd.config_file, *_dpd.config_line); } modbus_data = (modbus_option_data_t *)calloc(1, sizeof(modbus_option_data_t)); if (modbus_data == NULL) { DynamicPreprocessorFatalMessage("%s(%d) Failed to allocate memory for " "modbus_func data structure.\n", __FILE__, __LINE__); } /* Parsing time */ if (isdigit(params[0])) { /* Function code given as integer */ func_code = _dpd.SnortStrtoul(params, &endptr, 10); if ((func_code > 255) || (*endptr != '\0')) { DynamicPreprocessorFatalMessage("%s(%d): modbus_func requires a " "number between 0 and 255, or a valid function name.\n", *_dpd.config_file, *_dpd.config_line); } } else { /* Check the argument against the map in modbus_roptions.h */ size_t i; int parse_success = 0; for (i = 0; i < (sizeof(func_map) / sizeof(modbus_func_map_t)); i++) { if (strcmp(params, func_map[i].name) == 0) { parse_success = 1; func_code = func_map[i].func; break; } } if (!parse_success) { DynamicPreprocessorFatalMessage("%s(%d): modbus_func requires a " "number between 0 and 255, or a valid function name.\n", *_dpd.config_file, *_dpd.config_line); } } modbus_data->type = MODBUS_FUNC; modbus_data->arg = (uint8_t) func_code; *data = (void *)modbus_data; return 1; }
/* Function: SDFOptionInit * Purpose: Parses a SDF rule option. * Arguments: * name => Name of rule option * args => Arguments to rule option * data => Variable to save option data * Returns: 1 if successful * 0 if name is incorrect * Fatal Error if invalid arguments */ int SDFOptionInit(struct _SnortConfig *sc, char *name, char *args, void **data) { char *token, *endptr; unsigned long int tmpcount; SDFOptionData *sdf_data; if (name == NULL || args == NULL || data == NULL) return 0; if (strcasecmp(name, SDF_OPTION_NAME) != 0) return 0; sdf_data = (SDFOptionData *)calloc(1, sizeof(SDFOptionData)); if (sdf_data == NULL) { DynamicPreprocessorFatalMessage("%s(%d) Failed to allocate memory for " "SDF pattern data structure.", __FILE__, __LINE__); } /* Parse the count */ if (*args == '-') { free(sdf_data); DynamicPreprocessorFatalMessage("SDF rule cannot have a negative count:" " %s\n", args); } tmpcount = _dpd.SnortStrtoul(args, &endptr, 10); if (*endptr != ',') { free(sdf_data); DynamicPreprocessorFatalMessage("SDF rule configured with invalid " "arguments: %s\n", args); } if (tmpcount == 0 || tmpcount > 255) { free(sdf_data); DynamicPreprocessorFatalMessage("SDF rule needs to have a count between " " 1 - 255: %s\n", args); } sdf_data->count = (uint8_t)tmpcount; /* Take everything after the comma as a pattern. */ token = endptr + 1; if (*token == '\0') { free(sdf_data); DynamicPreprocessorFatalMessage("SDF rule missing pattern: %s ", args); } if (strcasecmp(token, SDF_CREDIT_KEYWORD) == 0) { sdf_data->pii = strdup(SDF_CREDIT_PATTERN_ALL); sdf_data->validate_func = SDFLuhnAlgorithm; } else if (strcasecmp(token, SDF_SOCIAL_KEYWORD) == 0) { sdf_data->pii = strdup(SDF_SOCIAL_PATTERN); sdf_data->validate_func = SDFSocialCheck; } else if (strcasecmp(token, SDF_SOCIAL_NODASHES_KEYWORD) == 0) { sdf_data->pii = strdup(SDF_SOCIAL_NODASHES_PATTERN); sdf_data->validate_func = SDFSocialCheck; } else if (strcasecmp(token, SDF_EMAIL_KEYWORD) == 0) { sdf_data->pii = strdup(SDF_EMAIL_PATTERN); } else { sdf_data->pii = strdup(token); sdf_data->validate_func = NULL; } *data = (void *)sdf_data; return 1; }
/* Parsing for the rule option */ static int SIP_MethodInit(struct _SnortConfig *sc, char *name, char *params, void **data) { int flags = 0, mask = 0; char *end = NULL; char *tok; int negated = 0; int numTokens = 0; SipMethodRuleOptData *sdata; SIPMethodNode *method; SIPConfig * sip_parsing_config; if (strcasecmp(name, SIP_ROPT__METHOD) != 0) return 0; /*Evaluate whether all the methods are in the PP configurations */ sip_parsing_config = getParsingSIPConfig(sc); if (NULL == sip_parsing_config) DynamicPreprocessorFatalMessage("%s(%d) => Configuration error!\n", *(_dpd.config_file), *(_dpd.config_line)); /* Must have arguments */ if (SIP_IsEmptyStr(params)) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to sip_method keyword\n", *(_dpd.config_file), *(_dpd.config_line)); } tok = strtok_r(params, ",", &end); if(!tok) DynamicPreprocessorFatalMessage("%s(%d) => missing argument to sip_method keyword\n", *(_dpd.config_file), *(_dpd.config_line)); while (NULL != tok) { numTokens++; if (tok[0] == '!') { negated = 1; tok++; } /*Only one method is allowed with !*/ if (negated && (numTokens > 1)) { DynamicPreprocessorFatalMessage("%s(%d) => %s, only one method is allowed with ! for %s.\n", *(_dpd.config_file), *(_dpd.config_line), tok, name); } method = SIP_FindMethod (sip_parsing_config->methods, tok, strlen (tok)); /*if method is not found, add it as a user defined method*/ if (NULL == method) { method = SIP_AddUserDefinedMethod(tok, &sip_parsing_config->methodsConfig, &sip_parsing_config->methods ); if (NULL == method) DynamicPreprocessorFatalMessage("%s(%d) => %s can't add new method to %s.\n", *(_dpd.config_file), *(_dpd.config_line), tok, name); _dpd.logMsg("%s(%d) => Add user defined method: %s to SIP preprocessor through rule.\n", *(_dpd.config_file), *(_dpd.config_line), method->methodName); } flags |= 1 << (method->methodFlag - 1); if (negated) mask |= 1 << (method->methodFlag - 1); tok = strtok_r(NULL, ", ", &end); } sdata = (SipMethodRuleOptData *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "sip preprocessor rule option.\n"); } sdata->flags = flags; sdata->mask = mask; *data = (void *)sdata; return 1; }
/* * Function: SMTP_ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ void SMTP_ParseArgs(SMTPConfig *config, char *args) { int ret = 0; char *arg; char *value; char errStr[ERRSTRLEN]; int errStrLen = ERRSTRLEN; int deprecated_options = 0; if ((config == NULL) || (args == NULL)) return; enablePort( config->ports, SMTP_DEFAULT_SERVER_PORT ); enablePort( config->ports, XLINK2STATE_DEFAULT_PORT ); enablePort( config->ports, SMTP_DEFAULT_SUBMISSION_PORT ); config->inspection_type = SMTP_STATELESS; config->max_command_line_len = DEFAULT_MAX_COMMAND_LINE_LEN; config->max_header_line_len = DEFAULT_MAX_HEADER_LINE_LEN; config->max_response_line_len = DEFAULT_MAX_RESPONSE_LINE_LEN; config->max_mime_depth = DEFAULT_MAX_MIME_DEPTH; config->memcap = DEFAULT_SMTP_MEMCAP; config->alert_xlink2state = 1; config->print_cmds = 1; config->enable_mime_decoding = 0; _dpd.fileAPI->set_mime_decode_config_defauts(&(config->decode_conf)); _dpd.fileAPI->set_mime_log_config_defauts(&(config->log_config)); config->log_config.email_hdrs_log_depth = DEFAULT_LOG_DEPTH; config->cmd_config = (SMTPCmdConfig *)calloc(CMD_LAST, sizeof(SMTPCmdConfig)); if (config->cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } *errStr = '\0'; arg = strtok(args, CONF_SEPARATORS); while ( arg != NULL ) { unsigned long val = 0; if ( !strcasecmp(CONF_PORTS, arg) ) { ret = ProcessPorts(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_INSPECTION_TYPE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_STATEFUL, value) ) { config->inspection_type = SMTP_STATEFUL; } else { config->inspection_type = SMTP_STATELESS; } } else if ( !strcasecmp(CONF_NORMALIZE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_NONE, value) ) { config->normalize = NORMALIZE_NONE; } else if ( !strcasecmp(CONF_ALL, value) ) { config->normalize = NORMALIZE_ALL; } else { config->normalize = NORMALIZE_CMDS; } } else if ( !strcasecmp(CONF_IGNORE_DATA, arg) ) { config->decode_conf.ignore_data = 1; } else if ( !strcasecmp(CONF_IGNORE_TLS_DATA, arg) ) { config->ignore_tls_data = 1; } else if ( !strcasecmp(CONF_MAX_COMMAND_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_command_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_HEADER_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_header_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_RESPONSE_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_response_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_NO_ALERTS, arg) ) { config->no_alerts = 1; } else if ( !strcasecmp(CONF_ALERT_UNKNOWN_CMDS, arg) ) { config->alert_unknown_cmds = 1; } else if ( !strcasecmp(CONF_INVALID_CMDS, arg) ) { /* Parse disallowed commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_ALERT, SMTP_CMD_TYPE_NORMAL); } else if ( !strcasecmp(CONF_VALID_CMDS, arg) ) { /* Parse allowed commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_NO_ALERT, SMTP_CMD_TYPE_NORMAL); } else if ( !strcasecmp(CONF_AUTH_CMDS, arg) ) { ret = ProcessCmds(config, errStr, errStrLen, ACTION_NO_ALERT, SMTP_CMD_TYPE_AUTH); } else if ( !strcasecmp(CONF_DATA_CMDS, arg) ) { ret = ProcessCmds(config, errStr, errStrLen, ACTION_NO_ALERT, SMTP_CMD_TYPE_DATA); } else if ( !strcasecmp(CONF_BDATA_CMDS, arg) ) { ret = ProcessCmds(config, errStr, errStrLen, ACTION_NO_ALERT, SMTP_CMD_TYPE_BDATA); } else if ( !strcasecmp(CONF_NORMALIZE_CMDS, arg) ) { /* Parse normalized commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_NORMALIZE, SMTP_CMD_TYPE_NORMAL); } else if ( !strcasecmp(CONF_ALT_MAX_COMMAND_LINE_LEN, arg) ) { /* Parse max line len for commands */ ret = ProcessAltMaxCmdLen(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_SMTP_MEMCAP, arg) ) { ret = _dpd.checkValueInRange(strtok(NULL, CONF_SEPARATORS), CONF_SMTP_MEMCAP, MIN_SMTP_MEMCAP, MAX_SMTP_MEMCAP, &val); config->memcap = (uint32_t)val; } else if ( !strcasecmp(CONF_MAX_MIME_MEM, arg) ) { ret = _dpd.checkValueInRange(strtok(NULL, CONF_SEPARATORS), CONF_MAX_MIME_MEM, MIN_MIME_MEM, MAX_MIME_MEM, &val); config->decode_conf.max_mime_mem = (int)val; } else if ( !strcasecmp(CONF_MAX_MIME_DEPTH, arg) ) { deprecated_options = 1; _dpd.logMsg("WARNING: %s(%d) => The SMTP config option 'max_mime_depth' is deprecated.\n", *(_dpd.config_file), *(_dpd.config_line)); ret = ProcessMaxMimeDepth(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_ENABLE_MIME_DECODING, arg) ) { deprecated_options = 1; _dpd.logMsg("WARNING: %s(%d) => The SMTP config option 'enable_mime_decoding' is deprecated.\n", *(_dpd.config_file), *(_dpd.config_line)); config->enable_mime_decoding = 1; } else if ( !strcasecmp(CONF_DISABLED, arg) ) { config->disabled = 1; } else if ( !strcasecmp(CONF_XLINK2STATE, arg) ) { ret = ProcessXlink2State(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_LOG_FILENAME, arg) ) { config->log_config.log_filename = 1; } else if ( !strcasecmp(CONF_LOG_MAIL_FROM, arg) ) { config->log_config.log_mailfrom = 1; } else if ( !strcasecmp(CONF_LOG_RCPT_TO, arg) ) { config->log_config.log_rcptto = 1; } else if ( !strcasecmp(CONF_LOG_EMAIL_HDRS, arg) ) { config->log_config.log_email_hdrs = 1; } else if ( !strcasecmp(CONF_EMAIL_HDRS_LOG_DEPTH, arg) ) { ret = ProcessLogDepth(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_PRINT_CMDS, arg) ) { config->print_cmds = 1; } else if(!_dpd.fileAPI->parse_mime_decode_args(&(config->decode_conf), arg, "SMTP")) { ret = 0; } else { DynamicPreprocessorFatalMessage("%s(%d) => Unknown SMTP configuration option %s\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if (ret == -1) { /* ** Fatal Error, log error and exit. */ if (*errStr) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), errStr); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } /* Get next token */ arg = strtok(NULL, CONF_SEPARATORS); } // NOTE: the default b64_depth is not defined in this file // but is equal to DEFAULT_MAX_MIME_DEPTH if(config->decode_conf.b64_depth == DEFAULT_MAX_MIME_DEPTH) { if(config->enable_mime_decoding) config->decode_conf.b64_depth = config->max_mime_depth; } else if(deprecated_options) { DynamicPreprocessorFatalMessage("%s(%d) => Cannot specify 'enable_mime_decoding' or 'max_mime_depth' with " "'b64_decode_depth'\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if(!config->log_config.email_hdrs_log_depth) { if(config->log_config.log_email_hdrs) { _dpd.logMsg("WARNING: %s(%d) => 'log_email_hdrs' enabled with 'email_hdrs_log_depth' = 0." "Email headers won't be logged. Please set 'email_hdrs_log_depth' > 0 to enable logging.\n", *(_dpd.config_file), *(_dpd.config_line)); } config->log_config.log_email_hdrs = 0; } }
/* Parsing for the rule option */ static int GTP_TypeInit(struct _SnortConfig *sc, char *name, char *params, void **data) { char *nextPara = NULL; char *tok; GTP_TypeRuleOptData *sdata; if (strcasecmp(name, GTP_ROPT__TYPE) != 0) return 0; /* Must have arguments */ if (_dpd.SnortIsStrEmpty(params)) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to gtp_type keyword\n", *(_dpd.config_file), *(_dpd.config_line)); } tok = strtok_r(params, ",", &nextPara); if(!tok) DynamicPreprocessorFatalMessage("%s(%d) => missing argument to gtp_type keyword\n", *(_dpd.config_file), *(_dpd.config_line)); sdata = (GTP_TypeRuleOptData *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "gtp preprocessor rule option.\n"); } while (NULL != tok) { bool found; if ( isdigit(*tok)) { found = GTP_AddTypeByNumer(sdata, tok); } else /*check keyword*/ { found = GTP_AddTypeByKeword(sdata, tok); } if (! found ) { DynamicPreprocessorFatalMessage(" %s(%d) => Bad value specified for %s. " "Please specify an integer between %d and %d, OR a correct name.\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__TYPE, MIN_GTP_TYPE_CODE, MAX_GTP_TYPE_CODE); } tok = strtok_r(NULL, ", ", &nextPara); } *data = (void *)sdata; return 1; }
/* * Function: SMTP_ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ void SMTP_ParseArgs(SMTPConfig *config, char *args) { int ret = 0; char *arg; char *value; char errStr[ERRSTRLEN]; int errStrLen = ERRSTRLEN; int b64_option = 0; int deprecated_options = 0; if ((config == NULL) || (args == NULL)) return; config->ports[SMTP_DEFAULT_SERVER_PORT / 8] |= 1 << (SMTP_DEFAULT_SERVER_PORT % 8); config->ports[XLINK2STATE_DEFAULT_PORT / 8] |= 1 << (XLINK2STATE_DEFAULT_PORT % 8); config->ports[SMTP_DEFAULT_SUBMISSION_PORT / 8] |= 1 << (SMTP_DEFAULT_SUBMISSION_PORT % 8); config->inspection_type = SMTP_STATELESS; config->max_command_line_len = DEFAULT_MAX_COMMAND_LINE_LEN; config->max_header_line_len = DEFAULT_MAX_HEADER_LINE_LEN; config->max_response_line_len = DEFAULT_MAX_RESPONSE_LINE_LEN; config->max_mime_depth = DEFAULT_MAX_MIME_DEPTH; config->max_mime_mem = DEFAULT_MAX_MIME_MEM; config->memcap = DEFAULT_SMTP_MEMCAP; config->alert_xlink2state = 1; config->print_cmds = 1; config->enable_mime_decoding = 0; config->b64_depth = DEFAULT_MAX_MIME_DEPTH; config->qp_depth = DEFAULT_MAX_MIME_DEPTH; config->uu_depth = DEFAULT_MAX_MIME_DEPTH; config->bitenc_depth = DEFAULT_MAX_MIME_DEPTH; config->max_depth = MIN_DEPTH; config->log_filename = 0; config->log_mailfrom = 0; config->log_rcptto = 0; config->log_email_hdrs = 0; config->email_hdrs_log_depth = DEFAULT_LOG_DEPTH; config->cmd_config = (SMTPCmdConfig *)calloc(CMD_LAST, sizeof(SMTPCmdConfig)); if (config->cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } *errStr = '\0'; arg = strtok(args, CONF_SEPARATORS); while ( arg != NULL ) { if ( !strcasecmp(CONF_PORTS, arg) ) { ret = ProcessPorts(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_INSPECTION_TYPE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_STATEFUL, value) ) { config->inspection_type = SMTP_STATEFUL; } else { config->inspection_type = SMTP_STATELESS; } } else if ( !strcasecmp(CONF_NORMALIZE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_NONE, value) ) { config->normalize = NORMALIZE_NONE; } else if ( !strcasecmp(CONF_ALL, value) ) { config->normalize = NORMALIZE_ALL; } else { config->normalize = NORMALIZE_CMDS; } } else if ( !strcasecmp(CONF_IGNORE_DATA, arg) ) { config->ignore_data = 1; } else if ( !strcasecmp(CONF_IGNORE_TLS_DATA, arg) ) { config->ignore_tls_data = 1; } else if ( !strcasecmp(CONF_MAX_COMMAND_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_command_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_HEADER_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_header_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_RESPONSE_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) return; config->max_response_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_NO_ALERTS, arg) ) { config->no_alerts = 1; } else if ( !strcasecmp(CONF_ALERT_UNKNOWN_CMDS, arg) ) { config->alert_unknown_cmds = 1; } else if ( !strcasecmp(CONF_INVALID_CMDS, arg) ) { /* Parse disallowed commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_ALERT); } else if ( !strcasecmp(CONF_VALID_CMDS, arg) ) { /* Parse allowed commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_NO_ALERT); } else if ( !strcasecmp(CONF_NORMALIZE_CMDS, arg) ) { /* Parse normalized commands */ ret = ProcessCmds(config, errStr, errStrLen, ACTION_NORMALIZE); } else if ( !strcasecmp(CONF_ALT_MAX_COMMAND_LINE_LEN, arg) ) { /* Parse max line len for commands */ ret = ProcessAltMaxCmdLen(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_SMTP_MEMCAP, arg) ) { ret = ProcessSmtpMemcap(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_MAX_MIME_MEM, arg) ) { ret = ProcessMaxMimeMem(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_MAX_MIME_DEPTH, arg) ) { deprecated_options = 1; _dpd.logMsg("WARNING: %s(%d) => The SMTP config option 'max_mime_depth' is deprecated.\n", *(_dpd.config_file), *(_dpd.config_line)); if(!b64_option) ret = ProcessMaxMimeDepth(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_ENABLE_MIME_DECODING, arg) ) { deprecated_options = 1; _dpd.logMsg("WARNING: %s(%d) => The SMTP config option 'enable_mime_decoding' is deprecated.\n", *(_dpd.config_file), *(_dpd.config_line)); if(!b64_option) config->enable_mime_decoding = 1; } else if ( !strcasecmp(CONF_DISABLED, arg) ) { config->disabled = 1; } else if ( !strcasecmp(CONF_XLINK2STATE, arg) ) { ret = ProcessXlink2State(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_LOG_FILENAME, arg) ) { config->log_filename = 1; } else if ( !strcasecmp(CONF_LOG_MAIL_FROM, arg) ) { config->log_mailfrom = 1; } else if ( !strcasecmp(CONF_LOG_RCPT_TO, arg) ) { config->log_rcptto = 1; } else if ( !strcasecmp(CONF_LOG_EMAIL_HDRS, arg) ) { config->log_email_hdrs = 1; } else if ( !strcasecmp(CONF_EMAIL_HDRS_LOG_DEPTH, arg) ) { ret = ProcessLogDepth(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_PRINT_CMDS, arg) ) { config->print_cmds = 1; } else if ( !strcasecmp(CONF_B64_DECODE, arg) ) { b64_option = 1; ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_B64_DECODE, DECODE_B64); } else if ( !strcasecmp(CONF_QP_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_QP_DECODE, DECODE_QP); } else if ( !strcasecmp(CONF_UU_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_UU_DECODE, DECODE_UU); } else if ( !strcasecmp(CONF_BITENC_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_BITENC_DECODE, DECODE_BITENC); } else { DynamicPreprocessorFatalMessage("%s(%d) => Unknown SMTP configuration option %s\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if (ret == -1) { /* ** Fatal Error, log error and exit. */ if (*errStr) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), errStr); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } /* Get next token */ arg = strtok(NULL, CONF_SEPARATORS); } if(!b64_option) { if(config->enable_mime_decoding) config->b64_depth = config->max_mime_depth; } else if(deprecated_options) { DynamicPreprocessorFatalMessage("%s(%d) => Cannot specify 'enable_mime_decoding' or 'max_mime_depth' with " "'b64_decode_depth'\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if(!config->email_hdrs_log_depth) { if(config->log_email_hdrs) { _dpd.logMsg("WARNING: %s(%d) => 'log_email_hdrs' enabled with 'email_hdrs_log_depth' = 0." "Email headers won't be logged. Please set 'email_hdrs_log_depth' > 0 to enable logging.\n", *(_dpd.config_file), *(_dpd.config_line)); } config->log_email_hdrs = 0; } }
/* Parsing for the rule option */ static int GTP_IEInit(struct _SnortConfig *sc, char *name, char *params, void **data) { char *nextPara = NULL; char *tok; GTP_InfoRuleOptData *sdata; bool found = false; if (strcasecmp(name, GTP_ROPT__IE) != 0) return 0; /* Must have arguments */ if (_dpd.SnortIsStrEmpty(params)) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to %s keyword\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__IE); } tok = strtok_r(params, ",", &nextPara); if(!tok) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to %s keyword\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__IE); } sdata = (GTP_InfoRuleOptData *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "gtp preprocessor rule option.\n"); } if ( isdigit(*tok)) { found = GTP_AddInfoElementByNumer(sdata, tok); } else { found = GTP_AddInfoElementByKeyword(sdata, tok); } if (! found ) { DynamicPreprocessorFatalMessage(" %s(%d) => Bad value specified for %s. " "Please specify an integer between %d and %d, OR a correct name.\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__IE, MIN_GTP_IE_CODE, MAX_GTP_IE_CODE); } if (!_dpd.SnortIsStrEmpty(nextPara)) { /* Must have only 1 argument*/ DynamicPreprocessorFatalMessage("%s, %s(%d) => rule option: This option has no arguments.\n", GTP_ROPT__IE, *(_dpd.config_file), *(_dpd.config_line)); } *data = (void *)sdata; return 1; }
/* * Function: IMAP_ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ void IMAP_ParseArgs(IMAPConfig *config, char *args) { int ret = 0; char *arg; char errStr[ERRSTRLEN]; int errStrLen = ERRSTRLEN; if ((config == NULL) || (args == NULL)) return; enablePort( config->ports, IMAP_DEFAULT_SERVER_PORT ); config->memcap = DEFAULT_IMAP_MEMCAP; _dpd.fileAPI->set_mime_decode_config_defauts(&(config->decode_conf)); _dpd.fileAPI->set_mime_log_config_defauts(&(config->log_config)); *errStr = '\0'; arg = strtok(args, CONF_SEPARATORS); while ( arg != NULL ) { unsigned long value = 0; if ( !strcasecmp(CONF_PORTS, arg) ) { ret = ProcessPorts(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_IMAP_MEMCAP, arg) ) { ret = _dpd.checkValueInRange(strtok(NULL, CONF_SEPARATORS), CONF_IMAP_MEMCAP, MIN_IMAP_MEMCAP, MAX_IMAP_MEMCAP, &value); config->memcap = (uint32_t)value; } else if ( !strcasecmp(CONF_MAX_MIME_MEM, arg) ) { ret = _dpd.checkValueInRange(strtok(NULL, CONF_SEPARATORS), CONF_MAX_MIME_MEM, MIN_MIME_MEM, MAX_MIME_MEM, &value); config->decode_conf.max_mime_mem = (int)value; } else if(!_dpd.fileAPI->parse_mime_decode_args(&(config->decode_conf), arg, "IMAP")) { ret = 0; } else if ( !strcasecmp(CONF_DISABLED, arg) ) { config->disabled = 1; } else { DynamicPreprocessorFatalMessage("%s(%d) => Unknown IMAP configuration option %s\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if (ret == -1) { /* ** Fatal Error, log error and exit. */ if (*errStr) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), errStr); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } /* Get next token */ arg = strtok(NULL, CONF_SEPARATORS); } }
/* Parsing for the rule option */ static int GTP_VersionInit(struct _SnortConfig *sc, char *name, char *params, void **data) { char *end = NULL; char *nextPara = NULL; char *tok; uint8_t *sdata; unsigned long gtpVersion; if (strcasecmp(name, GTP_ROPT__VERSION) != 0) return 0; /* Must have arguments */ if (_dpd.SnortIsStrEmpty(params)) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to %s keyword\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__VERSION); } tok = strtok_r(params, ",", &nextPara); if(!tok) { DynamicPreprocessorFatalMessage("%s(%d) => missing argument to %s keyword\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__VERSION); } sdata = (uint8_t *)calloc(1, sizeof(*sdata)); if (sdata == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "gtp preprocessor rule option.\n"); } gtpVersion = _dpd.SnortStrtoul(tok, &end, 10); DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Rule GTP version: %d.\n",gtpVersion)); if ( *end) { DynamicPreprocessorFatalMessage(" %s(%d) => Bad value specified for %s. " "Please specify an integer between %d and %d.\n", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__VERSION, MIN_GTP_VERSION_CODE, MAX_GTP_VERSION_CODE); } if ((gtpVersion > MAX_GTP_VERSION_CODE) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage("%s(%d) => Value specified for %s is out of " "bounds. Please specify an integer between %d and %d\n ", *(_dpd.config_file), *(_dpd.config_line), GTP_ROPT__VERSION, MIN_GTP_VERSION_CODE, MAX_GTP_VERSION_CODE); } *sdata = (uint8_t) gtpVersion; if (!_dpd.SnortIsStrEmpty(nextPara)) { /* Must have only 1 argument*/ DynamicPreprocessorFatalMessage("%s, %s(%d) => rule option: This option has only one argument.\n", GTP_ROPT__IE, *(_dpd.config_file), *(_dpd.config_line)); } *data = (void *)sdata; return 1; }
/* * Function: IMAP_ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ void IMAP_ParseArgs(IMAPConfig *config, char *args) { int ret = 0; char *arg; char errStr[ERRSTRLEN]; int errStrLen = ERRSTRLEN; if ((config == NULL) || (args == NULL)) return; config->ports[IMAP_DEFAULT_SERVER_PORT / 8] |= 1 << (IMAP_DEFAULT_SERVER_PORT % 8); config->memcap = DEFAULT_IMAP_MEMCAP; config->b64_depth = DEFAULT_DEPTH; config->qp_depth = DEFAULT_DEPTH; config->uu_depth = DEFAULT_DEPTH; config->bitenc_depth = DEFAULT_DEPTH; config->max_depth = MIN_DEPTH; *errStr = '\0'; arg = strtok(args, CONF_SEPARATORS); while ( arg != NULL ) { if ( !strcasecmp(CONF_PORTS, arg) ) { ret = ProcessPorts(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_IMAP_MEMCAP, arg) ) { ret = ProcessImapMemcap(config, errStr, errStrLen); } else if ( !strcasecmp(CONF_B64_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_B64_DECODE, DECODE_B64); } else if ( !strcasecmp(CONF_QP_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_QP_DECODE, DECODE_QP); } else if ( !strcasecmp(CONF_UU_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_UU_DECODE, DECODE_UU); } else if ( !strcasecmp(CONF_BITENC_DECODE, arg) ) { ret = ProcessDecodeDepth(config, errStr, errStrLen, CONF_BITENC_DECODE, DECODE_BITENC); } else if ( !strcasecmp(CONF_DISABLED, arg) ) { config->disabled = 1; } else { DynamicPreprocessorFatalMessage("%s(%d) => Unknown IMAP configuration option %s\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if (ret == -1) { /* ** Fatal Error, log error and exit. */ if (*errStr) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), errStr); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } /* Get next token */ arg = strtok(NULL, CONF_SEPARATORS); } }
static int ReadShmemDataFilesWithoutManifest() { struct dirent *de; DIR *dd; FreeShmemDataFileListFiles(); if ((dd = opendir(shmusr_ptr->path)) == NULL) { _dpd.errMsg("%s: Could not access %s: %s\n", MODULE_NAME, shmusr_ptr->path, strerror(errno)); return SF_EINVAL; } while (( de = readdir(dd) )) { char filename[PATH_MAX]; ShmemDataFileList *listinfo; const char *ext; int type; ext = strrchr(de->d_name , '.'); if ( ext == NULL || *(ext + 1) == '\0' ) continue; if ( strcasecmp(ext, ".blf") == 0 ) type = BLACK_LIST; else if ( strcasecmp(ext, ".wlf") == 0 ) type = WHITE_LIST; else continue; if ( FileListFull() ) { ShmemDataFileList **_temp = ShmemDataFileList_Realloc( filelist_ptr ); if ( !_temp ) { closedir(dd); if ( errno == ENOSPC ) { _dpd.errMsg("%s: Cannot load more than %u ip lists.", MODULE_NAME, MAX_IPLIST_FILES); return SF_ENOSPC; } DynamicPreprocessorFatalMessage("%s: Failed to allocate filelist_ptr: %s\n", MODULE_NAME, strerror(errno)); return SF_ENOMEM; } filelist_ptr = _temp; } listinfo = (ShmemDataFileList *)calloc(1, sizeof(*listinfo)); if ( listinfo == NULL ) { DynamicPreprocessorFatalMessage( "%s: Cannot allocate memory to store file information.\n", MODULE_NAME); } snprintf(filename, sizeof(filename), "%s/%s", shmusr_ptr->path, de->d_name); listinfo->filename = strdup(filename); if ( listinfo->filename == NULL ) { free(listinfo); closedir(dd); DynamicPreprocessorFatalMessage("%s: Error resolving filename: %s\n", MODULE_NAME, strerror(errno)); } listinfo->filetype = type; listinfo->listid = 0; memset(listinfo->zones, true, MAX_NUM_ZONES); filelist_ptr[filelist_count] = listinfo; filelist_count++; } closedir(dd); return SF_SUCCESS; }
/* Parses and processes the configuration arguments * supplied in the SSH preprocessor rule. * * PARAMETERS: * * argp: Pointer to string containing the config arguments. * * RETURNS: Nothing. */ static void ParseSSHArgs(SSHConfig *config, u_char* argp) { char* cur_tokenp = NULL; char* argcpyp = NULL; int port; if (config == NULL) return; config->MaxEncryptedPackets = SSH_DEFAULT_MAX_ENC_PKTS; config->MaxClientBytes = SSH_DEFAULT_MAX_CLIENT_BYTES; config->MaxServerVersionLen = SSH_DEFAULT_MAX_SERVER_VERSION_LEN; /* Set up default port to listen on */ config->ports[ PORT_INDEX( 22 ) ] |= CONV_PORT(22); /* Sanity check(s) */ if ( !argp ) { DisplaySSHConfig(config); return; } argcpyp = strdup( (char*) argp ); if ( !argcpyp ) { DynamicPreprocessorFatalMessage("Could not allocate memory to parse SSH options.\n"); return; } cur_tokenp = strtok( argcpyp, " "); while ( cur_tokenp ) { if ( !strcmp( cur_tokenp, SSH_SERVERPORTS_KEYWORD )) { /* If the user specified ports, remove '22' for now since * it now needs to be set explicitely. */ config->ports[ PORT_INDEX( 22 ) ] = 0; /* Eat the open brace. */ cur_tokenp = strtok( NULL, " "); if (( !cur_tokenp ) || ( cur_tokenp[0] != '{' )) { DynamicPreprocessorFatalMessage("Bad value specified for %s.\n", SSH_SERVERPORTS_KEYWORD); //free(argcpyp); //return; } cur_tokenp = strtok( NULL, " "); while (( cur_tokenp ) && ( cur_tokenp[0] != '}' )) { if ( !isdigit( (int)cur_tokenp[0] )) { DynamicPreprocessorFatalMessage("Bad port %s.\n", cur_tokenp ); //free(argcpyp); //return; } else { port = atoi( cur_tokenp ); if( port < 0 || port > MAX_PORTS ) { DynamicPreprocessorFatalMessage("Port value illegitimate: %s\n", cur_tokenp); //free(argcpyp); //return; } config->ports[ PORT_INDEX( port ) ] |= CONV_PORT(port); } cur_tokenp = strtok( NULL, " "); } } else if ( !strcmp( cur_tokenp, SSH_AUTODETECT_KEYWORD )) { config->AutodetectEnabled = 1; } else if ( !strcmp( cur_tokenp, SSH_MAX_ENC_PKTS_KEYWORD )) { cur_tokenp = strtok( NULL, " "); config->MaxEncryptedPackets = (uint16_t)ParseNumInRange(cur_tokenp, SSH_MAX_ENC_PKTS_KEYWORD, MIN_MAX_ENC_PKTS, MAX_MAX_ENC_PKTS); } else if (!strcmp( cur_tokenp, SSH_MAX_CLIENT_BYTES_KEYWORD )) { cur_tokenp = strtok( NULL, " "); config->MaxClientBytes = (uint16_t)ParseNumInRange(cur_tokenp, SSH_MAX_CLIENT_BYTES_KEYWORD, MIN_MAX_CLIENT_BYTES, MAX_MAX_CLIENT_BYTES); } else if ( !strcmp( cur_tokenp, SSH_MAX_SERVER_VERSION_KEYWORD )) { cur_tokenp = strtok( NULL, " "); config->MaxServerVersionLen = (uint16_t)ParseNumInRange(cur_tokenp, SSH_MAX_SERVER_VERSION_KEYWORD, MIN_MAX_SERVER_VERSION_LEN, MAX_MAX_SERVER_VERSION_LEN); } else if ( !strcmp( cur_tokenp, SSH_ENABLE_RESPOVERFLOW_KEYWORD )) { config->EnabledAlerts |= SSH_ALERT_RESPOVERFLOW; } else if ( !strcmp( cur_tokenp, SSH_ENABLE_CRC32_KEYWORD )) { config->EnabledAlerts |= SSH_ALERT_CRC32; } else if ( !strcmp( cur_tokenp, SSH_ENABLE_SECURECRT_KEYWORD )) { config->EnabledAlerts |= SSH_ALERT_SECURECRT; } else if ( !strcmp( cur_tokenp, SSH_ENABLE_PROTOMISMATCH_KEYWORD )) { config->EnabledAlerts |= SSH_ALERT_PROTOMISMATCH; } else if ( !strcmp( cur_tokenp, SSH_ENABLE_WRONGDIR_KEYWORD )) { config->EnabledAlerts |= SSH_ALERT_WRONGDIR; } #if 0 else if ( !strcmp( cur_tokenp, SSH_DISABLE_RULES_KEYWORD )) { config->DisableRules++; } #endif else if( !strcmp( cur_tokenp, SSH_ENABLE_PAYLOAD_SIZE )) { config->EnabledAlerts |= SSH_ALERT_PAYSIZE; } else if( !strcmp( cur_tokenp, SSH_ENABLE_UNRECOGNIZED_VER )) { config->EnabledAlerts |= SSH_ALERT_UNRECOGNIZED; } else { DynamicPreprocessorFatalMessage("Invalid argument: %s\n", cur_tokenp); return; } cur_tokenp = strtok( NULL, " " ); } DisplaySSHConfig(config); free(argcpyp); }
static ShmemDataFileList* processLineInManifest(char *manifest, char *line, int linenumber) { char* token; int tokenIndex = 0; ShmemDataFileList* listItem = NULL; char* nextPtr = line; char filename[PATH_MAX]; bool hasZone = false; if ((listItem = (ShmemDataFileList*)calloc(1,sizeof(ShmemDataFileList))) == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Cannot allocate memory to " "store reputation manifest file information\n", manifest, linenumber); return NULL; } while((token = strtok_r(nextPtr, MANIFEST_SEPARATORS, &nextPtr)) != NULL) { char *endStr; long zone_id; long list_id; DEBUG_WRAP(DebugMessage(DEBUG_REPUTATION, "Process reputation list token: %s\n",token );); switch (tokenIndex) { case 0: /* File name */ DEBUG_WRAP(DebugMessage(DEBUG_REPUTATION, "Reputation list filename: %s\n",token );); snprintf(filename, sizeof(filename), "%s/%s", shmusr_ptr->path,token); listItem->filename = strdup(filename); if (listItem->filename == NULL) { free(listItem); listItem = NULL; DynamicPreprocessorFatalMessage( "%s(%d) => Error resolving filename: %s\n", manifest, linenumber, strerror(errno)); } break; case 1: /* List ID */ list_id = _dpd.SnortStrtol( token, &endStr, 10); /*Ignore spaces in the end*/ endStr = ignoreStartSpace(endStr); if ( *endStr ) { DynamicPreprocessorFatalMessage("%s(%d) => Bad value (%s) specified for listID. " "Please specify an integer between %d and %li.\n", manifest, linenumber, token, 0, MAX_LIST_ID); } if ((list_id < 0) || (list_id > MAX_LIST_ID) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage(" %s(%d) => Value specified (%s) is out of " "bounds. Please specify an integer between %d and %li.\n", manifest, linenumber, token, 0, MAX_LIST_ID); } listItem->listid = (uint32_t) list_id; break; case 2: /* Action */ token = ignoreStartSpace(token); listItem->filetype = getFileTypeFromName(token); if (UNKNOWN_LIST == listItem->filetype) { DynamicPreprocessorFatalMessage(" %s(%d) => Unknown action specified (%s)." " Please specify a value: %s | %s | %s.\n", manifest, linenumber, token, WHITE_TYPE_KEYWORD, BLACK_TYPE_KEYWORD, MONITOR_TYPE_KEYWORD); } break; default: /*Ignore spaces in the beginning*/ token= ignoreStartSpace(token); if (!(*token)) break; zone_id = _dpd.SnortStrtol( token, &endStr, 10); /*Ignore spaces in the end*/ endStr = ignoreStartSpace(endStr); if ( *endStr ) { DynamicPreprocessorFatalMessage("%s(%d) => Bad value (%s) specified for zone. " "Please specify an integer between %d and %li.\n", manifest, linenumber, token, 0, MAX_NUM_ZONES - 1); } if ((zone_id < 0) || (zone_id >= MAX_NUM_ZONES ) || (errno == ERANGE)) { DynamicPreprocessorFatalMessage(" %s(%d) => Value specified (%s) for zone is " "out of bounds. Please specify an integer between %d and %li.\n", manifest, linenumber, token, 0, MAX_NUM_ZONES - 1); } listItem->zones[zone_id] = true; hasZone = true; }
/* * Function: SMTP_ParseArgs(char *) * * Purpose: Process the preprocessor arguments from the rules file and * initialize the preprocessor's data struct. This function doesn't * have to exist if it makes sense to parse the args in the init * function. * * Arguments: args => argument list * * Returns: void function * */ void SMTP_ParseArgs(char *args) { int ret = 0; char *arg; char *value; char errStr[ERRSTRLEN]; int errStrLen = ERRSTRLEN; if (args == NULL) { return; } /* Set config to defaults */ memset(&_smtp_config, 0, sizeof(SMTPConfig)); _smtp_config.ports[SMTP_DEFAULT_SERVER_PORT / 8] |= 1 << (SMTP_DEFAULT_SERVER_PORT % 8); _smtp_config.ports[XLINK2STATE_DEFAULT_PORT / 8] |= 1 << (XLINK2STATE_DEFAULT_PORT % 8); _smtp_config.ports[SMTP_DEFAULT_SUBMISSION_PORT / 8] |= 1 << (SMTP_DEFAULT_SUBMISSION_PORT % 8); _smtp_config.inspection_type = SMTP_STATELESS; _smtp_config.max_command_line_len = DEFAULT_MAX_COMMAND_LINE_LEN; _smtp_config.max_header_line_len = DEFAULT_MAX_HEADER_LINE_LEN; _smtp_config.max_response_line_len = DEFAULT_MAX_RESPONSE_LINE_LEN; _smtp_config.alert_xlink2state = 1; _smtp_config.print_cmds = 1; _smtp_cmd_config = (SMTPCmdConfig *)calloc(CMD_LAST, sizeof(SMTPCmdConfig)); if (_smtp_cmd_config == NULL) { DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for SMTP " "command structure\n", *(_dpd.config_file), *(_dpd.config_line)); } *errStr = '\0'; arg = strtok(args, CONF_SEPARATORS); while ( arg != NULL ) { if ( !strcasecmp(CONF_PORTS, arg) ) { ret = ProcessPorts(errStr, errStrLen); } else if ( !strcasecmp(CONF_INSPECTION_TYPE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_STATEFUL, value) ) { _smtp_config.inspection_type = SMTP_STATEFUL; } else { _smtp_config.inspection_type = SMTP_STATELESS; } } else if ( !strcasecmp(CONF_NORMALIZE, arg) ) { value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } if ( !strcasecmp(CONF_NONE, value) ) { _smtp_config.normalize = NORMALIZE_NONE; } else if ( !strcasecmp(CONF_ALL, value) ) { _smtp_config.normalize = NORMALIZE_ALL; } else { _smtp_config.normalize = NORMALIZE_CMDS; } } else if ( !strcasecmp(CONF_IGNORE_DATA, arg) ) { _smtp_config.ignore_data = 1; } else if ( !strcasecmp(CONF_IGNORE_TLS_DATA, arg) ) { _smtp_config.ignore_tls_data = 1; } else if ( !strcasecmp(CONF_MAX_COMMAND_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } _smtp_config.max_command_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_HEADER_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } _smtp_config.max_header_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_MAX_RESPONSE_LINE_LEN, arg) ) { char *endptr; value = strtok(NULL, CONF_SEPARATORS); if ( value == NULL ) { return; } _smtp_config.max_response_line_len = strtol(value, &endptr, 10); } else if ( !strcasecmp(CONF_NO_ALERTS, arg) ) { _smtp_config.no_alerts = 1; } else if ( !strcasecmp(CONF_ALERT_UNKNOWN_CMDS, arg) ) { _smtp_config.alert_unknown_cmds = 1; } else if ( !strcasecmp(CONF_INVALID_CMDS, arg) ) { /* Parse disallowed commands */ ret = ProcessCmds(errStr, errStrLen, ACTION_ALERT); } else if ( !strcasecmp(CONF_VALID_CMDS, arg) ) { /* Parse allowed commands */ ret = ProcessCmds(errStr, errStrLen, ACTION_NO_ALERT); } else if ( !strcasecmp(CONF_NORMALIZE_CMDS, arg) ) { /* Parse normalized commands */ ret = ProcessCmds(errStr, errStrLen, ACTION_NORMALIZE); } else if ( !strcasecmp(CONF_ALT_MAX_COMMAND_LINE_LEN, arg) ) { /* Parse max line len for commands */ ret = ProcessAltMaxCmdLen(errStr, errStrLen); } else if ( !strcasecmp(CONF_XLINK2STATE, arg) ) { ret = ProcessXlink2State(errStr, errStrLen); } else if ( !strcasecmp(CONF_PRINT_CMDS, arg) ) { _smtp_config.print_cmds = 1; } else { DynamicPreprocessorFatalMessage("%s(%d) => Unknown SMTP configuration option %s\n", *(_dpd.config_file), *(_dpd.config_line), arg); } if (ret == -1) { /* ** Fatal Error, log error and exit. */ if (*errStr) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), errStr); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } /* Get next token */ arg = strtok(NULL, CONF_SEPARATORS); } PrintConfig(); }
void SMTP_CheckConfig(SMTPConfig *pPolicyConfig, tSfPolicyUserContextId context) { int max = -1; SMTPConfig *defaultConfig = (SMTPConfig *)sfPolicyUserDataGetDefault(context); if (pPolicyConfig == defaultConfig) { if (!pPolicyConfig->max_mime_mem) pPolicyConfig->max_mime_mem = DEFAULT_MAX_MIME_MEM; if(!pPolicyConfig->b64_depth || !pPolicyConfig->qp_depth || !pPolicyConfig->uu_depth || !pPolicyConfig->bitenc_depth) { pPolicyConfig->max_depth = MAX_DEPTH; return; } else { if(max < pPolicyConfig->b64_depth) max = pPolicyConfig->b64_depth; if(max < pPolicyConfig->qp_depth) max = pPolicyConfig->qp_depth; if(max < pPolicyConfig->bitenc_depth) max = pPolicyConfig->bitenc_depth; if(max < pPolicyConfig->uu_depth) max = pPolicyConfig->uu_depth; pPolicyConfig->max_depth = max; } if (!pPolicyConfig->memcap) pPolicyConfig->memcap = DEFAULT_SMTP_MEMCAP; if(pPolicyConfig->disabled && !pPolicyConfig->email_hdrs_log_depth) pPolicyConfig->email_hdrs_log_depth = DEFAULT_LOG_DEPTH; } else if (defaultConfig == NULL) { if (pPolicyConfig->max_mime_mem) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: max_mime_mem must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->b64_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: b64_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->qp_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: qp_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->uu_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: uu_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->bitenc_depth > -1) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: bitenc_decode_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (pPolicyConfig->memcap) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: memcap must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } if(pPolicyConfig->log_email_hdrs && pPolicyConfig->email_hdrs_log_depth) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: email_hdrs_log_depth must be " "configured in the default config.\n", *(_dpd.config_file), *(_dpd.config_line)); } } else { pPolicyConfig->max_mime_mem = defaultConfig->max_mime_mem; pPolicyConfig->max_depth = defaultConfig->max_depth; pPolicyConfig->memcap = defaultConfig->memcap; pPolicyConfig->email_hdrs_log_depth = defaultConfig->email_hdrs_log_depth; if(pPolicyConfig->disabled) { pPolicyConfig->b64_depth = defaultConfig->b64_depth; pPolicyConfig->qp_depth = defaultConfig->qp_depth; pPolicyConfig->uu_depth = defaultConfig->uu_depth; pPolicyConfig->bitenc_depth = defaultConfig->bitenc_depth; return; } if(!pPolicyConfig->b64_depth && defaultConfig->b64_depth) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: Cannot enable unlimited Base64 decoding" " in non-default config without turning on unlimited Base64 decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->b64_depth && (pPolicyConfig->b64_depth > defaultConfig->b64_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: b64_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->b64_depth, defaultConfig->b64_depth); } if(!pPolicyConfig->qp_depth && defaultConfig->qp_depth) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: Cannot enable unlimited Quoted-Printable decoding" " in non-default config without turning on unlimited Quoted-Printable decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->qp_depth && (pPolicyConfig->qp_depth > defaultConfig->qp_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: qp_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->qp_depth, defaultConfig->qp_depth); } if(!pPolicyConfig->uu_depth && defaultConfig->uu_depth ) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: Cannot enable unlimited Unix-to-Unix decoding" " in non-default config without turning on unlimited Unix-to-Unix decoding in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->uu_depth && (pPolicyConfig->uu_depth > defaultConfig->uu_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: uu_decode_depth value %d in non-default config" " cannot exceed default config's value %d.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->uu_depth, defaultConfig->uu_depth); } if(!pPolicyConfig->bitenc_depth && defaultConfig->bitenc_depth) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: Cannot enable unlimited Non-Encoded MIME attachment extraction" " in non-default config without turning on unlimited Non-Encoded MIME attachment extraction in the default " " config.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if(defaultConfig->bitenc_depth && (pPolicyConfig->bitenc_depth > defaultConfig->bitenc_depth)) { DynamicPreprocessorFatalMessage("%s(%d) => SMTP: bitenc_decode_depth value %d in non-default config " " cannot exceed default config's value.\n", *(_dpd.config_file), *(_dpd.config_line), pPolicyConfig->bitenc_depth, defaultConfig->bitenc_depth); } } }