On Tue, Aug 26, 2003 at 12:24:11AM +0200, Sander Smeenk wrote: > > Really, the way to fix this package X needs data Y to be up-to-date is to: > > a) separate data from the package (Nessus plugins are available in the > > 'nessus-plugins' package and can be updated separately, for example) > > snort has that. snort-rules-default is the default set of rules found on > snort.org for the release that is in debian, almost always updated when a > new debian-release of the package is done. People can start packaging > their own rulesets, maybe even local rulesets or something.
Sure, I'm not saying that snort does not have it. I'm just saying that maybe you should consider upgrading the one in stable. The differences in format are known and you should be able to find a way to convert older rules set. > > > b) provide some way to retrieve new data (signatures, attacks, whatever) > > either: downloading them from the main site directly (as > > nessus-update-plugins does) or providing backported packages (and have them > > included in stable revisiones. > > This problem only exists for snort packages that aren't going to be > updated, like the ones that reach stable. The unstable package is up to > date enough to have all correct rules, imho. You can convince the stable release manager to put a new snort-rules-default package into sarge, for example, 6 months after it is released. It's easier to do that than to try to push a new upstream version into sarge, and you will be providing the new rules users might want. In any case, I was thinking on the lines of a separate (not packaged) method to download rules directly from snort.org. Please take a look at the 'nessus-update-plugins' to see what I mean. > The other thing is, snort.org's people quickly start to drop old rule > formats when newer formats are used. Should I be the one that has to > convert every rule back to the old format to have stable users of snort > safe and sound? It'll take alot of time. And I believe it is not always > scriptable. You are, after all, the snort package maintainer. If you don't want to do this you can try to find people who might volunteer to do the work for stable and provide a new snort-rules-default package for stable maybe converting some of the new rules which are no longer valid. Granted, some information might be lost in the conversion and some rules might not be converted, but still, better than no updates. > So, although it sounds nice to have scripts to update rulefiles, I don't > really see it happening, because of the problems amentioned above. If no one works to see that happen it will never be. > > > c) have a way to determine properly when new data needs a new engine and > > won't work with older versions and warn the user about it. This means that > > the engine needs to be programmed beforehand to understand a given dataset > > version and complain when the dataset is of a newer (and potentially > > worthless) version. > > Well. Snort just fails to start if it can't parse the rule files. And > usually that is with every major upstream release. :( [Short version: see the patch below.] [Long version: follows] That's obviously, suboptimal, snort should be able to determine in some way from a rules file if the format is a version it knows or it isn't. C'mon version headers are not unheard of, just take a look at the header of any HTML file in www.debian.org, it will tell you precisely which DTD to use to be able to "understand" it. It wouldn't be so difficult [1] to have snort analyse the rules file before including and determine if its rules can, or cannot, be added. Of course, that would be mean improving the way rules files are parsed currently. There is currently no distinction between snort's configuration and the rules files themselves (pv.config_file in snort.c) but if they were separated the ParseRulesFile in snort's parser.c could be rewritten to verify the call to ParseRule and not proceed if there is an indication that the rules belong to a new version. The adjointed patch (probably very ugly, untested and maybe broken) provides that functionality. If the snort parser encounters a place of the file which has 'version X' with X > SNORT_MAJOR_VERSION then it will not go on reading the rest of the rules file. That way you can have rules in one file which are read by older snort versions and rules that cannot (maybe because the Parser has been enhanced to included new formats). Regards Javi
--- parser.c.old 2003-08-26 01:04:50.000000000 +0200 +++ parser.c 2003-08-26 01:20:40.000000000 +0200 @@ -55,6 +55,8 @@ #include "threshold.h" #include "snort.h" +#define SNORT_MAJOR_VERSION 2 +/* SNORT_VERSION should probably be defined in the snort generic headers */ ListHead Alert; /* Alert Block Header */ ListHead Log; /* Log Block Header */ @@ -128,6 +130,7 @@ int stored_file_line = file_line; char *saved_line = NULL; int continuation = 0; + int continueread = 1; char *new_line = NULL; struct stat file_stat; /* for include path testing */ @@ -198,7 +201,7 @@ /* loop thru each file line and send it to the rule parser */ - while((fgets(buf, STD_BUF, thefp)) != NULL) + while( continueread >0 && (fgets(buf, STD_BUF, thefp)) != NULL) { /* * inc the line counter so the error messages know which line to @@ -248,7 +251,7 @@ DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, "[*] Processing rule: %s\n", index);); - ParseRule(thefp, index, inclevel); + continueread = ParseRule(thefp, index, inclevel); if(new_line != NULL) { @@ -454,14 +457,16 @@ * Arguments: rule => rule string * inclevel => nr of stacked "include"s * - * Returns: void function + * Returns: integer, if greater than 0 the processor will keep reading + * the rules file otherwise it will stop * ***************************************************************************/ -void ParseRule(FILE *rule_file, char *prule, int inclevel) +int ParseRule(FILE *rule_file, char *prule, int inclevel) { char **toks; /* dbl ptr for mSplit call, holds rule tokens */ int num_toks; /* holds number of tokens found by mSplit */ int rule_type; /* rule type enumeration variable */ + int version; /* version of the rules below */ char rule[PARSERULE_SIZE]; int protocol = 0; char *tmp; @@ -493,6 +498,19 @@ /* handle non-rule entries */ switch(rule_type) { + case RULE_VERSION: + DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Version\n");); + version = strtol(toks[1], NULL, 10); + if ( errno == ERANGE || errno == EINVAL ) { + FatalError("%s(%d) => Version is not a number %s\n", + file_name, file_line, toks[1]); + } + if ( version > SNORT_MAJOR_VERSION ) { + ErrorMessage("%s(%d) => Version %s not supported, rules file will not be read any longer\n", file_name, file_line, toks[1]); + return 0; + } + return 1 ; + case RULE_PASS: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Pass\n");); break; @@ -522,22 +540,22 @@ ParseRulesFile(tmp, inclevel + 1); - return; + return 1; case RULE_VAR: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Variable\n");); VarDefine(toks[1], toks[2]); - return; + return 1; case RULE_PREPROCESS: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Preprocessor\n");); ParsePreprocessor(rule); - return; + return 1; case RULE_OUTPUT: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Output Plugin\n");); ParseOutputPlugin(rule); - return; + return 1; case RULE_ACTIVATE: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Activation rule\n");); @@ -550,21 +568,21 @@ case RULE_CONFIG: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Rule file config\n");); ParseConfig(rule); - return; + return 1; case RULE_DECLARE: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Rule type declaration\n");); ParseRuleTypeDeclaration(rule_file, rule); - return; + return 1; case RULE_UNKNOWN: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Unknown rule type, might be declared\n");); ParseDeclaredRuleType(rule); - return; + return 1; default: DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Invalid input: %s\n", prule);); - return; + return 1; } if(num_toks < 7) @@ -580,7 +598,7 @@ " at the end of the line, make sure there are no\n" " carriage returns before the end of this line)\n", file_name, file_line); - return; + return 1; } @@ -713,7 +731,7 @@ free(toks[i]); } - return; + return 1; } /**************************************************************************** @@ -1772,6 +1790,9 @@ FatalError("%s(%d) => Unknown rule type (%s)\n", file_name, file_line, func); } + if(!strcasecmp(func, "version")) + return RULE_VERSION; + if(!strcasecmp(func, "log")) return RULE_LOG; 53a54 > #define RULE_VERSION 12
pgpQsA4PpYYZU.pgp
Description: PGP signature