diff --git a/src/detect-tls.c b/src/detect-tls.c index 5f4b7835ab..6f3b7b9616 100644 --- a/src/detect-tls.c +++ b/src/detect-tls.c @@ -93,6 +93,7 @@ static int DetectTlsStoreMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, u */ void DetectTlsRegister (void) { sigmatch_table[DETECT_AL_TLS_SUBJECT].name = "tls.subject"; + sigmatch_table[DETECT_AL_TLS_SUBJECT].desc = "Match TLS/SSL certificate Subject field"; sigmatch_table[DETECT_AL_TLS_SUBJECT].Match = NULL; sigmatch_table[DETECT_AL_TLS_SUBJECT].AppLayerMatch = DetectTlsSubjectMatch; sigmatch_table[DETECT_AL_TLS_SUBJECT].alproto = ALPROTO_TLS; @@ -101,6 +102,7 @@ void DetectTlsRegister (void) { sigmatch_table[DETECT_AL_TLS_SUBJECT].RegisterTests = DetectTlsSubjectRegisterTests; sigmatch_table[DETECT_AL_TLS_ISSUERDN].name = "tls.issuerdn"; + sigmatch_table[DETECT_AL_TLS_ISSUERDN].desc = "Match TLS/SSL certificate IssuerDN field"; sigmatch_table[DETECT_AL_TLS_ISSUERDN].Match = NULL; sigmatch_table[DETECT_AL_TLS_ISSUERDN].AppLayerMatch = DetectTlsIssuerDNMatch; sigmatch_table[DETECT_AL_TLS_ISSUERDN].alproto = ALPROTO_TLS; @@ -109,6 +111,7 @@ void DetectTlsRegister (void) { sigmatch_table[DETECT_AL_TLS_ISSUERDN].RegisterTests = DetectTlsIssuerDNRegisterTests; sigmatch_table[DETECT_AL_TLS_FINGERPRINT].name = "tls.fingerprint"; + sigmatch_table[DETECT_AL_TLS_FINGERPRINT].desc = "Match TLS/SSL certificate SHA1 fingerprint"; sigmatch_table[DETECT_AL_TLS_FINGERPRINT].Match = NULL; sigmatch_table[DETECT_AL_TLS_FINGERPRINT].AppLayerMatch = DetectTlsFingerprintMatch; sigmatch_table[DETECT_AL_TLS_FINGERPRINT].alproto = ALPROTO_TLS; @@ -117,6 +120,7 @@ void DetectTlsRegister (void) { sigmatch_table[DETECT_AL_TLS_FINGERPRINT].RegisterTests = NULL; sigmatch_table[DETECT_AL_TLS_STORE].name = "tls.store"; + sigmatch_table[DETECT_AL_TLS_STORE].desc = "Store certificate on disk"; sigmatch_table[DETECT_AL_TLS_STORE].Match = NULL; sigmatch_table[DETECT_AL_TLS_STORE].AppLayerMatch = DetectTlsStoreMatch; sigmatch_table[DETECT_AL_TLS_STORE].alproto = ALPROTO_TLS; diff --git a/src/detect.c b/src/detect.c index 338090ead1..36c72a7d36 100644 --- a/src/detect.c +++ b/src/detect.c @@ -4566,17 +4566,79 @@ int SigGroupCleanup (DetectEngineCtx *de_ctx) { return 0; } -void SigTableList(void) +static inline void PrintFeatureList(int flags, char sep) +{ + int prev = 0; + if (flags & SIGMATCH_NOOPT) { + printf("No option"); + prev = 1; + } + if (flags & SIGMATCH_IPONLY_COMPAT) { + if (prev == 1) + printf("%c", sep); + printf("IP only rule"); + prev = 1; + } + if (flags & SIGMATCH_DEONLY_COMPAT) { + if (prev == 1) + printf("%c", sep); + printf("IP only rule"); + prev = 1; + } + if (flags & SIGMATCH_PAYLOAD) { + if (prev == 1) + printf("%c", sep); + printf("payload inspecting rule"); + prev = 1; + } + if (prev == 0) { + printf("none"); + } +} + +void SigTableList(const char *keyword) { size_t size = sizeof(sigmatch_table) / sizeof(SigTableElmt); size_t i; - printf("=====Supported keywords=====\n"); - for (i = 0; i < size; i++) { - if (sigmatch_table[i].name != NULL) - printf("- %s\n", sigmatch_table[i].name); - } + if (keyword == NULL) { + printf("=====Supported keywords=====\n"); + for (i = 0; i < size; i++) { + if (sigmatch_table[i].name != NULL) + printf("- %s\n", sigmatch_table[i].name); + } + } else if (!strcmp("all", keyword)) { + printf("name;description;app layer;features\n"); + for (i = 0; i < size; i++) { + if (sigmatch_table[i].name != NULL) { + printf("%s;", sigmatch_table[i].name); + if (sigmatch_table[i].desc) { + printf("%s", sigmatch_table[i].desc); + } + /* Build feature */ + printf(";%s;", + TmModuleAlprotoToString(sigmatch_table[i].alproto)); + PrintFeatureList(sigmatch_table[i].flags, ':'); + printf("\n"); + } + } + } else { + for (i = 0; i < size; i++) { + if ((sigmatch_table[i].name != NULL) && + !strcmp(sigmatch_table[i].name, keyword)) { + printf("%s\n", sigmatch_table[i].name); + if (sigmatch_table[i].desc) { + printf("Description: %s\n", sigmatch_table[i].desc); + } + printf("Protocol: %s\n", + TmModuleAlprotoToString(sigmatch_table[i].alproto)); + printf("Features: "); + PrintFeatureList(sigmatch_table[i].flags, ','); + printf("\n"); + } + } + } return; } diff --git a/src/detect.h b/src/detect.h index 8af730fde9..0bbcd54ddc 100644 --- a/src/detect.h +++ b/src/detect.h @@ -860,6 +860,8 @@ typedef struct SigTableElmt_ { uint8_t flags; char *name; + char *desc; + } SigTableElmt; #define SIG_GROUP_HEAD_MPM_COPY (1) @@ -1115,7 +1117,7 @@ void SigAddressPrepareBidirectionals (DetectEngineCtx *); char *DetectLoadCompleteSigPath(char *sig_file); int SigLoadSignatures (DetectEngineCtx *, char *, int); -void SigTableList(void); +void SigTableList(const char *keyword); 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 35748b8116..f9114a914d 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -490,7 +490,7 @@ void usage(const char *progname) printf("\t--fatal-unittests : enable fatal failure on unittest error\n"); #endif /* UNITTESTS */ printf("\t--list-app-layer-protos : list supported app layer protocols\n"); - printf("\t--list-keywords : list all keywords implemented by the engine\n"); + printf("\t--list-keywords[=any|]: list keywords implemented by the engine\n"); #ifdef __SC_CUDA_SUPPORT__ printf("\t--list-cuda-cards : list cuda supported cards\n"); #endif @@ -681,6 +681,7 @@ int main(int argc, char **argv) int list_cuda_cards = 0; int list_runmodes = 0; int list_keywords = 0; + const char *keyword_info = NULL; const char *runmode_custom_mode = NULL; int daemon = 0; #ifndef OS_WIN32 @@ -763,7 +764,7 @@ int main(int argc, char **argv) {"list-unittests", 0, &list_unittests, 1}, {"list-cuda-cards", 0, &list_cuda_cards, 1}, {"list-runmodes", 0, &list_runmodes, 1}, - {"list-keywords", 0, &list_keywords, 1}, + {"list-keywords", optional_argument, &list_keywords, 1}, {"runmode", required_argument, NULL, 0}, {"engine-analysis", 0, &engine_analysis, 1}, #ifdef OS_WIN32 @@ -917,7 +918,9 @@ int main(int argc, char **argv) RunModeListRunmodes(); exit(EXIT_SUCCESS); } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) { - // do nothing + if (optarg) { + keyword_info = optarg; + } } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) { runmode_custom_mode = optarg; } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) { @@ -1419,7 +1422,7 @@ int main(int argc, char **argv) /* hardcoded initialization code */ SigTableSetup(); /* load the rule keywords */ if (list_keywords) { - SigTableList(); + SigTableList(keyword_info); exit(EXIT_FAILURE); } TmqhSetup();