From 8cc82c7241daa78425dfacf9f8fae498c22f4020 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 8 Nov 2011 17:54:58 +0100 Subject: [PATCH] Add -S commandline option that loads a rule file exclusively. Issue #338. --- src/detect.c | 43 +++++++++++++++++++++++-------------------- src/detect.h | 2 +- src/suricata.c | 20 +++++++++++++++++--- src/util-error.c | 1 + src/util-error.h | 1 + 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/detect.c b/src/detect.c index a6460c8e70..a02bf9e3a5 100644 --- a/src/detect.c +++ b/src/detect.c @@ -513,9 +513,10 @@ int DetectLoadSigFile(DetectEngineCtx *de_ctx, char *sig_file, int *sigs_tot) { * \brief Load signatures * \param de_ctx Pointer to the detection engine context * \param sig_file Filename holding signatures + * \param sig_file_exclusive File passed in 'sig_file' should be loaded exclusively. * \retval -1 on error */ -int SigLoadSignatures(DetectEngineCtx *de_ctx, char *sig_file) +int SigLoadSignatures(DetectEngineCtx *de_ctx, char *sig_file, int sig_file_exclusive) { SCEnter(); @@ -571,27 +572,29 @@ int SigLoadSignatures(DetectEngineCtx *de_ctx, char *sig_file) } /* ok, let's load signature files from the general config */ - rule_files = ConfGetNode("rule-files"); - if (rule_files != NULL) { - TAILQ_FOREACH(file, &rule_files->head, next) { - sfile = DetectLoadCompleteSigPath(file->val); - SCLogDebug("Loading rule file: %s", sfile); - - r = DetectLoadSigFile(de_ctx, sfile, &sigtotal); - cntf++; - if (r > 0) { - cnt += r; - } else if (r == 0){ - SCLogWarning(SC_ERR_NO_RULES, "No rules loaded from %s", sfile); - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); - } - } else if (r < 0){ - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); + if (!(sig_file != NULL && sig_file_exclusive == TRUE)) { + rule_files = ConfGetNode("rule-files"); + if (rule_files != NULL) { + TAILQ_FOREACH(file, &rule_files->head, next) { + sfile = DetectLoadCompleteSigPath(file->val); + SCLogDebug("Loading rule file: %s", sfile); + + r = DetectLoadSigFile(de_ctx, sfile, &sigtotal); + cntf++; + if (r > 0) { + cnt += r; + } else if (r == 0){ + SCLogWarning(SC_ERR_NO_RULES, "No rules loaded from %s", sfile); + if (de_ctx->failure_fatal == 1) { + exit(EXIT_FAILURE); + } + } else if (r < 0){ + if (de_ctx->failure_fatal == 1) { + exit(EXIT_FAILURE); + } } + SCFree(sfile); } - SCFree(sfile); } } diff --git a/src/detect.h b/src/detect.h index 2ecd9bb4d8..0264524250 100644 --- a/src/detect.h +++ b/src/detect.h @@ -1043,7 +1043,7 @@ int SigGroupBuild(DetectEngineCtx *); int SigGroupCleanup (DetectEngineCtx *de_ctx); void SigAddressPrepareBidirectionals (DetectEngineCtx *); -int SigLoadSignatures (DetectEngineCtx *, char *); +int SigLoadSignatures (DetectEngineCtx *, char *, int); void SigTableSetup(void); int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p); diff --git a/src/suricata.c b/src/suricata.c index 2d5648bab0..457f033ce1 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -411,7 +411,8 @@ void usage(const char *progname) #ifdef IPFW printf("\t-d : run in inline ipfw divert mode\n"); #endif /* IPFW */ - printf("\t-s : path to signature file (optional)\n"); + printf("\t-s : path to signature file loaded in addition to suricata.yaml settings (optional)\n"); + printf("\t-S : path to signature file loaded exclusively (optional)\n"); printf("\t-l : default log directory\n"); #ifndef OS_WIN32 printf("\t-D : run as daemon\n"); @@ -576,6 +577,7 @@ int main(int argc, char **argv) int opt; char pcap_dev[128]; char *sig_file = NULL; + int sig_file_exclusive = FALSE; char *conf_filename = NULL; char *pid_filename = NULL; #ifdef UNITTESTS @@ -688,7 +690,7 @@ int main(int argc, char **argv) /* getopt_long stores the option index here. */ int option_index = 0; - char short_opts[] = "c:Dhi:l:q:d:r:us:U:VF:"; + char short_opts[] = "c:Dhi:l:q:d:r:us:S:U:VF:"; while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) { switch (opt) { @@ -1016,7 +1018,19 @@ int main(int argc, char **argv) } break; case 's': + if (sig_file != NULL) { + SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S."); + exit(EXIT_FAILURE); + } + sig_file = optarg; + break; + case 'S': + if (sig_file != NULL) { + SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S."); + exit(EXIT_FAILURE); + } sig_file = optarg; + sig_file_exclusive = TRUE; break; case 'u': #ifdef UNITTESTS @@ -1442,7 +1456,7 @@ int main(int argc, char **argv) ActionInitConfig(); - if (SigLoadSignatures(de_ctx, sig_file) < 0) { + if (SigLoadSignatures(de_ctx, sig_file, sig_file_exclusive) < 0) { if (sig_file == NULL) { SCLogError(SC_ERR_OPENING_FILE, "Signature file has not been provided"); } else { diff --git a/src/util-error.c b/src/util-error.c index c7edde4373..dedd00eaac 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -209,6 +209,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_AFP_CREATE); CASE_CODE (SC_ERR_AFP_READ); CASE_CODE (SC_ERR_AFP_DISPATCH); + CASE_CODE (SC_ERR_CMD_LINE); default: return "UNKNOWN_ERROR"; diff --git a/src/util-error.h b/src/util-error.h index e7d3d184de..e8e8223e7f 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -222,6 +222,7 @@ typedef enum { SC_ERR_AFP_DISPATCH, SC_ERR_NO_AF_PACKET, SC_ERR_PCAP_FILE_DELETE_FAILED, + SC_ERR_CMD_LINE, } SCError; const char *SCErrorToString(SCError);