NORETURN void DynamicPreprocessorFatalMessage(const char *format, ...) { char buf[STD_BUF]; va_list ap; va_start(ap, format); vsnprintf(buf, STD_BUF, format, ap); va_end(ap); buf[STD_BUF - 1] = '\0'; _dpd.fatalMsg("%s", buf); exit(1); }
/* 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( u_char* argp ) { if(!_dpd.streamAPI) { _dpd.fatalMsg("SetupSSH(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreproc( ProcessSSH, PRIORITY_APPLICATION, PP_SSH ); ParseSSHArgs( argp ); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ssh", (void *)&sshPerfStats, 0, _dpd.totalPerfStats); #endif }
int LoadConfig( const u_char* conf, SSLConfig* cfg ) { ParseContext ctx; u_char* conf_copy = NULL; ConfigToken TopLevelTokens[] = { Token_Server, Token_EOF }; ConfigToken token = Token_Unknown; error_buffer[0] = 0; conf_copy = (u_char*) malloc( strlen( conf ) + 1 ); strcpy( conf_copy, conf ); memset( &ctx, 0, sizeof(ctx) ); ctx.input = conf_copy; ctx.config = cfg; do { token = ParseOneOf( &ctx, TopLevelTokens, ARRAY_SIZE( TopLevelTokens ) ); if( token == Token_Server ) { if( ParseServer( &ctx ) == CONFIG_PARSE_ERROR ) token = CONFIG_PARSE_ERROR; } } while ( token == Token_Server ); free( conf_copy ); conf_copy = ctx.input = NULL; /* make sure we have at least one server set up */ if( token != CONFIG_PARSE_ERROR && ctx.config->server_cnt == 0 ) { sprintf( error_buffer, "%s: at least one SSL server's configuration is expected", ERROR_PREFIX ); token = CONFIG_PARSE_ERROR; } if( token == CONFIG_PARSE_ERROR ) { if( strlen( error_buffer ) ) { _dpd.fatalMsg( "%s(%d) => %s", *(_dpd.config_file), *(_dpd.config_line), error_buffer ); } return CONFIG_PARSE_ERROR; } PrintSSLConfig( ctx.config ); return 0; }
/* 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); }