/* Check ports & services */ static int DNP3PortCheck(dnp3_config_t *config, SFSnortPacket *packet) { #ifdef TARGET_BASED int16_t app_id = _dpd.streamAPI->get_application_protocol_id(packet->stream_session_ptr); /* call to get_application_protocol_id gave an error */ if (app_id == SFTARGET_UNKNOWN_PROTOCOL) return DNP3_FAIL; /* this is positively identified as something non-dnp3 */ if (app_id && (app_id != dnp3_app_id)) return DNP3_FAIL; /* this is identified as dnp3 */ if (app_id == dnp3_app_id) return DNP3_OK; /* fall back to port check */ #endif if (config->ports[PORT_INDEX(packet->src_port)] & CONV_PORT(packet->src_port)) return DNP3_OK; if (config->ports[PORT_INDEX(packet->dst_port)] & CONV_PORT(packet->dst_port)) return DNP3_OK; return DNP3_FAIL; }
/* Take a port object's ports and add them to the preprocessor's port array. */ void AddPortsToConf(SDFConfig *config, OptTreeNode *otn) { int i, nports; char *src_parray, *dst_parray; RuleTreeNode *rtn; if (config == NULL || otn == NULL) return; /* RTNs vary based on which policy the rule appears in. */ rtn = otn->proto_nodes[_dpd.getParserPolicy()]; /* Take the source port object and add ports to the preproc's array */ src_parray = _dpd.portObjectCharPortArray(NULL, rtn->src_portobject, &nports); if (src_parray == 0) { /* This is an "any" port object! */ for (i = 0; i < MAX_PORTS/8; i++) { config->src_ports[i] = 0xFF; } } else { /* iterate through an array of ports, add each one. */ for (i = 0; i < MAX_PORTS; i++) { if (src_parray[i] == 1) config->src_ports[PORT_INDEX(i)] |= CONV_PORT(i); } } /* Repeat for destination ports. */ dst_parray = _dpd.portObjectCharPortArray(NULL, rtn->dst_portobject, &nports); if (dst_parray == 0) { /* This is an "any" port object! */ for (i = 0; i < MAX_PORTS/8; i++) { config->dst_ports[i] = 0xFF; } } else { /* iterate through an array of ports, add each one. */ for (i = 0; i < MAX_PORTS; i++) { if (dst_parray[i] == 1) config->dst_ports[PORT_INDEX(i)] |= CONV_PORT(i); } } /* Cleanup */ if (src_parray) free(src_parray); if (dst_parray) free(dst_parray); }
/******************************************************************** * Function: GTP_ParsePortList() * * Parses a port list and adds bits associated with the ports * parsed to a bit array. * * Arguments: * char ** * Pointer to the pointer to the current position in the * configuration line. This is updated to the current position * after parsing the IP list. * uint8_t * * Pointer to the port array mask to set bits for the ports * parsed. * * Returns: * GTP_Ret * GTP_SUCCESS if we were able to successfully parse the * port list. * GTP_FAILURE if an error occured in parsing the port list. * ********************************************************************/ static void GTP_ParsePortList(char **ptr, uint8_t *port_array) { long int port = -1; char* cur_tokenp = *ptr; /* If the user specified ports, remove GTP_C_PORT for now since * it now needs to be set explicitly. */ port_array[ PORT_INDEX( GTP_C_PORT ) ] = 0; port_array[ PORT_INDEX( GTP_C_PORT_V0 ) ] = 0; DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Port configurations: %s\n",*ptr ););
/* Print a Modbus config */ static void ModbusPrintConfig(modbus_config_t *config) { int index; int newline = 1; if (config == NULL) return; _dpd.logMsg("Modbus config: \n"); _dpd.logMsg(" Ports:\n"); /* Loop through port array & print, 5 ports per line */ for (index = 0; index < MAX_PORTS; index++) { if (config->ports[PORT_INDEX(index)] & CONV_PORT(index)) { _dpd.logMsg("\t%d", index); if ( !((newline++) % 5) ) { _dpd.logMsg("\n"); } } } _dpd.logMsg("\n"); }
/* Display the configuration for the DNS preprocessor. * * PARAMETERS: None. * * RETURNS: Nothing. */ static void PrintDNSConfig() { int index; _dpd.logMsg("DNS config: \n"); #if 0 _dpd.logMsg(" Autodetection: %s\n", dns_config.autodetect ? "ENABLED":"DISABLED"); #endif _dpd.logMsg(" DNS Client rdata txt Overflow Alert: %s\n", dns_config.enabled_alerts & DNS_ALERT_RDATA_OVERFLOW ? "ACTIVE" : "INACTIVE" ); _dpd.logMsg(" Obsolete DNS RR Types Alert: %s\n", dns_config.enabled_alerts & DNS_ALERT_OBSOLETE_TYPES ? "ACTIVE" : "INACTIVE" ); _dpd.logMsg(" Experimental DNS RR Types Alert: %s\n", dns_config.enabled_alerts & DNS_ALERT_EXPERIMENTAL_TYPES ? "ACTIVE" : "INACTIVE" ); /* Printing ports */ _dpd.logMsg(" Ports:"); for(index = 0; index < MAX_PORTS; index++) { if( dns_config.ports[ PORT_INDEX(index) ] & CONV_PORT(index) ) { _dpd.logMsg(" %d", index); } } _dpd.logMsg("\n"); }
/* Print a DNP3 config */ static void PrintDNP3Config(dnp3_config_t *config) { int index, newline = 1; if (config == NULL) return; _dpd.logMsg("DNP3 config: \n"); if (config->disabled) _dpd.logMsg(" DNP3: INACTIVE\n"); _dpd.logMsg(" Memcap: %d\n", config->memcap); _dpd.logMsg(" Check Link-Layer CRCs: %s\n", config->check_crc ? "ENABLED":"DISABLED"); _dpd.logMsg(" Ports:\n"); /* Loop through port array & print, 5 ports per line */ for (index = 0; index < MAX_PORTS; index++) { if (config->ports[PORT_INDEX(index)] & CONV_PORT(index)) { _dpd.logMsg("\t%d", index); if ( !((newline++) % 5) ) { _dpd.logMsg("\n"); } } } _dpd.logMsg("\n"); }
static inline void SSLSetPort(SSLPP_config_t *config, int port) { if (config == NULL) return; config->ports[ PORT_INDEX(port) ] |= CONV_PORT(port); }
/* Display the configuration for the GTP preprocessor. * * PARAMETERS: * * GTPConfig *config: GTP preprocessor configuration. * * RETURNS: Nothing. */ static void DisplayGTPConfig(GTPConfig *config) { int index; int newline; if (config == NULL) return; _dpd.logMsg("GTP config: \n"); /* Traverse list, printing ports, 5 per line */ newline = 1; _dpd.logMsg(" Ports:\n"); for(index = 0; index < MAXPORTS; index++) { if( config->ports[ PORT_INDEX(index) ] & CONV_PORT(index) ) { _dpd.logMsg("\t%d", index); if ( !((newline++)% 5) ) _dpd.logMsg("\n"); } } _dpd.logMsg("\n"); DEBUG_WRAP(DisplayMsgTypes(config)); DEBUG_WRAP(DisplayInfoElements(config)); }
/* ********************************************************************** * Validates given port as an SIP server port. * * PARAMETERS: * * port: Port to validate. * * RETURNS: SIP_TRUE, if the port is indeed an SIP server port. * SIP_FALSE, otherwise. ***********************************************************************/ static inline int CheckSIPPort( uint16_t port ) { if ( sip_eval_config->ports[ PORT_INDEX(port) ] & CONV_PORT( port ) ) { return SIP_TRUE; } return SIP_FALSE; }
/* Validates given port as an DNS server port. * * PARAMETERS: * * port: Port to validate. * * RETURNS: DNS_TRUE, if the port is indeed an DNS server port. * DNS_FALSE, otherwise. */ static inline int CheckDNSPort( u_int16_t port ) { if ( dns_config.ports[ PORT_INDEX(port) ] & CONV_PORT( port ) ) { return 1; } return 0; }
static void SSLPP_print_config(SSLPP_config_t *config) { char buf[1024]; /* For syslog printing */ int i; int newline; if (config == NULL) return; memset(buf, 0, sizeof(buf)); _dpd.logMsg("SSLPP config:\n"); _dpd.logMsg(" Encrypted packets: %s\n", config->flags & SSLPP_DISABLE_FLAG ? "not inspected" : "inspected"); _dpd.logMsg(" Ports:\n"); for(newline = 0, i = 0; i < MAXPORTS; i++) { if( config->ports[ PORT_INDEX(i) ] & CONV_PORT(i) ) { SFP_snprintfa(buf, sizeof(buf), " %5d", i); if( !((++newline) % 5) ) { SFP_snprintfa(buf, sizeof(buf), "\n"); _dpd.logMsg(buf); memset(buf, 0, sizeof(buf)); } } } if(newline % 5) SFP_snprintfa(buf, sizeof(buf), "\n"); _dpd.logMsg(buf); if ( config->flags & SSLPP_TRUSTSERVER_FLAG ) { _dpd.logMsg(" Server side data is trusted\n"); } if ( config->pki_dir ) { _dpd.logMsg(" PKI Directory: %s\n", config->pki_dir); } if ( config->ssl_rules_dir ) { _dpd.logMsg(" SSL Rules Directory: %s\n", config->ssl_rules_dir); } #ifdef ENABLE_HA _dpd.logMsg(" SSL HA enabled : %s\n", config->enable_ssl_ha ? "YES" : "NO" ); #endif _dpd.logMsg(" Maximum SSL Heartbeat length: %d\n", config->max_heartbeat_len); }
/* Validates given port as an SSH server port. * * PARAMETERS: * * port: Port to validate. * * RETURNS: SSH_TRUE, if the port is indeed an SSH server port. * SSH_FALSE, otherwise. */ static INLINE int CheckSSHPort( uint16_t port ) { if ( ssh_eval_config->ports[ PORT_INDEX(port) ] & CONV_PORT( port ) ) { return SSH_TRUE; } return SSH_FALSE; }
/* Validates given port as an SSH server port. * * PARAMETERS: * * port: Port to validate. * * RETURNS: SSH_TRUE, if the port is indeed an SSH server port. * SSH_FALSE, otherwise. */ static inline int CheckSSHPort( u_int16_t port ) { if ( ssh_config.ports[ PORT_INDEX(port) ] & CONV_PORT( port ) ) { return SSH_TRUE; } return SSH_FALSE; }
/* Take a DNP3 config + Snort policy, iterate through ports, register PAF callback. */ int DNP3AddPortsToPaf(struct _SnortConfig *sc, dnp3_config_t *config, tSfPolicyId policy_id) { unsigned int i; for (i = 0; i < MAX_PORTS; i++) { if (config->ports[PORT_INDEX(i)] & CONV_PORT(i)) { DNP3PafRegisterPort(sc, (uint16_t) i, policy_id); } } return DNP3_OK; }
static void ParseSinglePort(modbus_config_t *config, char *token) { /* single port number */ char *endptr; unsigned long portnum = _dpd.SnortStrtoul(token, &endptr, 10); if ((*endptr != '\0') || (portnum >= MAX_PORTS)) { _dpd.fatalMsg("%s(%d) Bad modbus port number: %s\n" "Port number must be an integer between 0 and 65535.\n", *_dpd.config_file, *_dpd.config_line, token); } /* Good port number! */ config->ports[PORT_INDEX(portnum)] |= CONV_PORT(portnum); }
/* Display the configuration for the SIP preprocessor. * * PARAMETERS: * * SIPConfig *config: SIP preprocessor configuration. * * RETURNS: Nothing. */ static void DisplaySIPConfig(SIPConfig *config) { int index; int newline; SIPMethodNode *method; if (config == NULL) return; _dpd.logMsg("SIP config: \n"); _dpd.logMsg(" Max number of sessions: %d %s \n", config->maxNumSessions, config->maxNumSessions == SIP_DEFAULT_MAX_SESSIONS ? "(Default)" : "" ); _dpd.logMsg(" Status: %s\n", config->disabled ? "DISABLED":"ENABLED"); if (config->disabled) return; _dpd.logMsg(" Ignore media channel: %s\n", config->ignoreChannel ? "ENABLED":"DISABLED"); _dpd.logMsg(" Max URI length: %d %s \n", config->maxUriLen, config->maxUriLen == SIP_DEFAULT_MAX_URI_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max Call ID length: %d %s \n", config->maxCallIdLen, config->maxCallIdLen == SIP_DEFAULT_MAX_CALL_ID_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max Request name length: %d %s \n", config->maxRequestNameLen, config->maxRequestNameLen == SIP_DEFAULT_MAX_REQUEST_NAME_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max From length: %d %s \n", config->maxFromLen, config->maxFromLen == SIP_DEFAULT_MAX_FROM_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max To length: %d %s \n", config->maxToLen, config->maxToLen == SIP_DEFAULT_MAX_TO_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max Via length: %d %s \n", config->maxViaLen, config->maxViaLen == SIP_DEFAULT_MAX_VIA_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max Contact length: %d %s \n", config->maxContactLen, config->maxContactLen == SIP_DEFAULT_MAX_CONTACT_LEN ? "(Default)" : "" ); _dpd.logMsg(" Max Content length: %d %s \n", config->maxContentLen, config->maxContentLen == SIP_DEFAULT_MAX_CONTENT_LEN ? "(Default)" : "" ); /* Traverse list, printing ports, 5 per line */ newline = 1; _dpd.logMsg(" Ports:\n"); for(index = 0; index < MAXPORTS; index++) { if( config->ports[ PORT_INDEX(index) ] & CONV_PORT(index) ) { _dpd.logMsg("\t%d", index); if ( !((newline++)% 5) ) { _dpd.logMsg("\n"); } } } _dpd.logMsg("\n"); _dpd.logMsg(" Methods:\n"); _dpd.logMsg("\t%s ", config->methodsConfig == SIP_METHOD_DEFAULT ? "(Default)" : ""); method = config->methods; while(NULL != method) { _dpd.logMsg(" %s", method->methodName); method = method->nextm; } _dpd.logMsg("\n"); }
SFP_ret_t SFP_ports(ports_tbl_t port_tbl, char *str, SFP_errstr_t errstr) { char *tok; char *saveptr; char end_brace_found = 0; char port_found = 0; if(!str) { SET_ERR("%s", "Invalid pointer"); return SFP_ERROR; } if((tok = strtok_r(str, " ", &saveptr)) == NULL) { SET_ERR("%s", "No ports specified"); return SFP_ERROR; } /* This string had better start with a '{' and end with a '}', or else! */ if(strcmp(tok, "{")) { SET_ERR("Malformed port list: %s. Expecting a leading '{ '", tok); return SFP_ERROR; } while((tok = strtok_r(NULL, " ", &saveptr)) != NULL) { char *port_end; long int port; str = NULL; if(end_brace_found) { SET_ERR("Last character of a port list must be '}': %s", tok); return SFP_ERROR; } if(!strcmp(tok, "}")) { end_brace_found = 1; continue; } errno = 0; port = strtol(tok, &port_end, 10); if((port_end == tok) || (*port_end && *port_end != '}') || (errno == ERANGE)) { SET_ERR("Unable to parse: %s", tok); return SFP_ERROR; } if(port < 0 || port > MAXPORTS-1) { SET_ERR("Port out of range: %s", tok); return SFP_ERROR; } port_tbl[ PORT_INDEX(port) ] |= CONV_PORT(port); port_found = 1; } if(!end_brace_found) { SET_ERR("%s", "No end brace found"); return SFP_ERROR; } if(!port_found) { SET_ERR("%s", "No ports specified"); return SFP_ERROR; } CLR_ERR(); return SFP_SUCCESS; }
/* Display the configuration for the SSH preprocessor. * * PARAMETERS: None. * * RETURNS: Nothing. */ static void DisplaySSHConfig(SSHConfig *config) { int index; int newline; if (config == NULL) return; _dpd.logMsg("SSH config: \n"); _dpd.logMsg(" Autodetection: %s\n", config->AutodetectEnabled ? "ENABLED":"DISABLED"); _dpd.logMsg(" Challenge-Response Overflow Alert: %s\n", config->EnabledAlerts & SSH_ALERT_RESPOVERFLOW ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" SSH1 CRC32 Alert: %s\n", config->EnabledAlerts & SSH_ALERT_CRC32 ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Server Version String Overflow Alert: %s\n", config->EnabledAlerts & SSH_ALERT_SECURECRT ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Protocol Mismatch Alert: %s\n", config->EnabledAlerts & SSH_ALERT_PROTOMISMATCH? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Bad Message Direction Alert: %s\n", config->EnabledAlerts & SSH_ALERT_WRONGDIR ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Bad Payload Size Alert: %s\n", config->EnabledAlerts & SSH_ALERT_PAYSIZE ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Unrecognized Version Alert: %s\n", config->EnabledAlerts & SSH_ALERT_UNRECOGNIZED ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Max Encrypted Packets: %d %s \n", config->MaxEncryptedPackets, config->MaxEncryptedPackets == SSH_DEFAULT_MAX_ENC_PKTS ? "(Default)" : "" ); _dpd.logMsg(" Max Server Version String Length: %d %s \n", config->MaxServerVersionLen, config->MaxServerVersionLen == SSH_DEFAULT_MAX_SERVER_VERSION_LEN ? "(Default)" : "" ); if ( config->EnabledAlerts & (SSH_ALERT_RESPOVERFLOW | SSH_ALERT_CRC32)) { _dpd.logMsg(" MaxClientBytes: %d %s \n", config->MaxClientBytes, config->MaxClientBytes == SSH_DEFAULT_MAX_CLIENT_BYTES ? "(Default)" : "" ); } /* Traverse list, printing ports, 5 per line */ newline = 1; _dpd.logMsg(" Ports:\n"); for(index = 0; index < MAX_PORTS; index++) { if( config->ports[ PORT_INDEX(index) ] & CONV_PORT(index) ) { _dpd.logMsg("\t%d", index); if ( !((newline++)% 5) ) { _dpd.logMsg("\n"); } } } _dpd.logMsg("\n"); }
/* 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); }
/* 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( u_char* argp ) { char* cur_tokenp = NULL; char* argcpyp = NULL; int port; /* Set up default port to listen on */ ssh_config.ports[ PORT_INDEX( 22 ) ] |= CONV_PORT(22); /* Sanity check(s) */ if ( !argp ) { DisplaySSHConfig(); return; } argcpyp = strdup( (char*) argp ); if ( !argcpyp ) { _dpd.fatalMsg("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. */ ssh_config.ports[ PORT_INDEX( 22 ) ] = 0; /* Eat the open brace. */ cur_tokenp = strtok( NULL, " "); if (( !cur_tokenp ) || ( cur_tokenp[0] != '{' )) { _dpd.fatalMsg("Bad value specified for %s.\n", SSH_SERVERPORTS_KEYWORD); free(argcpyp); return; } cur_tokenp = strtok( NULL, " "); while (( cur_tokenp ) && ( cur_tokenp[0] != '}' )) { if ( !isdigit( cur_tokenp[0] )) { _dpd.fatalMsg("Bad port %s.\n", cur_tokenp ); free(argcpyp); return; } else { port = atoi( cur_tokenp ); if( port < 0 || port > MAX_PORTS ) { _dpd.fatalMsg("Port value illegitimate: %s\n", cur_tokenp); free(argcpyp); return; } ssh_config.ports[ PORT_INDEX( port ) ] |= CONV_PORT(port); } cur_tokenp = strtok( NULL, " "); } } else if ( !strcmp( cur_tokenp, SSH_AUTODETECT_KEYWORD )) { ssh_config.AutodetectEnabled++; } else if ( !strcmp( cur_tokenp, SSH_MAX_ENC_PKTS_KEYWORD )) { cur_tokenp = strtok( NULL, " "); if (( !cur_tokenp ) || !isdigit(cur_tokenp[0]) ) { _dpd.logMsg("Bad value specified for %s." "Reverting to default value %d. ", SSH_MAX_ENC_PKTS_KEYWORD, SSH_DEFAULT_MAX_ENC_PKTS ); } else { ssh_config.MaxEncryptedPackets = (u_int16_t) atoi( cur_tokenp ); } } else if (!strcmp( cur_tokenp, SSH_MAX_CLIENT_BYTES_KEYWORD )) { cur_tokenp = strtok( NULL, " "); if (( !cur_tokenp ) || !isdigit(cur_tokenp[0]) ) { _dpd.logMsg("Bad value specified for %s." "Reverting to default value %d. ", SSH_MAX_CLIENT_BYTES_KEYWORD, SSH_DEFAULT_MAX_CLIENT_BYTES ); } else { ssh_config.MaxClientBytes = (u_int16_t) atoi( cur_tokenp ); } } else if ( !strcmp( cur_tokenp, SSH_DISABLE_GOBBLES_KEYWORD )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_GOBBLES; } else if ( !strcmp( cur_tokenp, SSH_DISABLE_CRC32_KEYWORD )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_CRC32; } else if ( !strcmp( cur_tokenp, SSH_DISABLE_SECURECRT_KEYWORD )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_SECURECRT; } else if ( !strcmp( cur_tokenp, SSH_DISABLE_PROTOMISMATCH_KEYWORD )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_PROTOMISMATCH; } else if ( !strcmp( cur_tokenp, SSH_DISABLE_WRONGDIR_KEYWORD )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_WRONGDIR; } else if ( !strcmp( cur_tokenp, SSH_DISABLE_RULES_KEYWORD )) { ssh_config.DisableRules++; } else if( !strcmp( cur_tokenp, SSH_DISABLE_PAYLOAD_SIZE )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_PAYSIZE; } else if( !strcmp( cur_tokenp, SSH_DISABLE_UNRECOGNIZED_VER )) { ssh_config.EnabledAlerts &= ~SSH_ALERT_UNRECOGNIZED; } else { _dpd.fatalMsg("Invalid argument: %s\n", cur_tokenp); return; } cur_tokenp = strtok( NULL, " " ); } DisplaySSHConfig(); free(argcpyp); }
/* Display the configuration for the SSH preprocessor. * * PARAMETERS: None. * * RETURNS: Nothing. */ static void DisplaySSHConfig() { int index; int newline; SSHPortNode* cur_nodep = NULL; _dpd.logMsg("SSH config: \n"); _dpd.logMsg(" Autodetection: %s\n", ssh_config.AutodetectEnabled ? "ENABLED":"DISABLED"); _dpd.logMsg(" GOBBLES Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_GOBBLES ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" SSH1 CRC32 Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_CRC32 ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Server Version String Overflow Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_SECURECRT ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Protocol Mismatch Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_PROTOMISMATCH? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Bad Message Direction Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_WRONGDIR ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Bad Payload Size Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_PAYSIZE ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Unrecognized Version Alert: %s\n", ssh_config.EnabledAlerts & SSH_ALERT_UNRECOGNIZED ? "ENABLED" : "DISABLED" ); _dpd.logMsg(" Max Encrypted Packets: %d %s \n", ssh_config.MaxEncryptedPackets, ssh_config.MaxEncryptedPackets == SSH_DEFAULT_MAX_ENC_PKTS ? "(Default)" : "" ); if ( ssh_config.EnabledAlerts & (SSH_ALERT_GOBBLES | SSH_ALERT_CRC32)) { _dpd.logMsg(" MaxClientBytes: %d %s \n", ssh_config.MaxClientBytes, ssh_config.MaxClientBytes == SSH_DEFAULT_MAX_CLIENT_BYTES ? "(Default)" : "" ); } /* Traverse list, printing ports, 5 per line */ newline = 1; _dpd.logMsg(" Ports:\n"); for(index = 0; index < MAX_PORTS; index++) { if( ssh_config.ports[ PORT_INDEX(index) ] & CONV_PORT(index) ) { _dpd.logMsg("\t%d", index); if ( !((newline++)% 5) ) { _dpd.logMsg("\n"); } } } _dpd.logMsg("\n"); }
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); } }
static void ParseModbusArgs(modbus_config_t *config, char *args) { char *saveptr; char *token; /* Set default port */ config->ports[PORT_INDEX(MODBUS_PORT)] |= CONV_PORT(MODBUS_PORT); /* No args? Stick to the default. */ if (args == NULL) return; token = strtok_r(args, " ", &saveptr); while (token != NULL) { if (strcmp(token, "ports") == 0) { unsigned nPorts = 0; /* Un-set the default port */ config->ports[PORT_INDEX(MODBUS_PORT)] = 0; /* Parse ports */ token = strtok_r(NULL, " ", &saveptr); if (token == NULL) { _dpd.fatalMsg("%s(%d) Missing argument for Modbus 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 ) { _dpd.fatalMsg("%s(%d) Bad Modbus 'ports' argument: '%s'\n" "Argument to Modbus 'ports' must be an integer, or a list " "enclosed in { } braces.\n", *_dpd.config_file, *_dpd.config_line, token); } } else { _dpd.fatalMsg("%s(%d) Failed to parse modbus argument: %s\n", *_dpd.config_file, *_dpd.config_line, token); } token = strtok_r(NULL, " ", &saveptr); } }
/* 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); }