/** * \brief this function is used to add the parsed "id" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param idstr pointer to the user provided "id" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectSslVersionSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str) { DetectSslVersionData *ssl = NULL; SigMatch *sm = NULL; if (DetectSignatureSetAppProto(s, ALPROTO_TLS) != 0) return -1; ssl = DetectSslVersionParse(str); if (ssl == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_AL_SSL_VERSION; sm->ctx = (void *)ssl; SigMatchAppendSMToList(s, sm, g_tls_generic_list_id); return 0; error: if (ssl != NULL) DetectSslVersionFree(ssl); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to add the parsed "id" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param idstr pointer to the user provided "id" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectSslVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectSslVersionData *ssl = NULL; SigMatch *sm = NULL; ssl = DetectSslVersionParse(str); if (ssl == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_AL_SSL_VERSION; sm->ctx = (void *)ssl; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } s->alproto = ALPROTO_TLS; return 0; error: if (ssl != NULL) DetectSslVersionFree(ssl); if (sm != NULL) SCFree(sm); return -1; }
/** * \test DetectSslVersionTestParse02 is a test to make sure that we parse the * "ssl_version" option correctly when given an invalid ssl_version option * it should return ssl = NULL */ static int DetectSslVersionTestParse02(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("2.5"); FAIL_IF_NOT_NULL(ssl); DetectSslVersionFree(ssl); PASS; }
/** * \test DetectSslVersionTestParse01 is a test to make sure that we parse the * "ssl_version" option correctly when given valid ssl_version option */ static int DetectSslVersionTestParse01(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("SSlv3"); FAIL_IF_NULL(ssl); FAIL_IF_NOT(ssl->data[SSLv3].ver == SSL_VERSION_3); DetectSslVersionFree(ssl); PASS; }
/** * \test DetectSslVersionTestParse02 is a test to make sure that we parse the * "ssl_version" option correctly when given an invalid ssl_version option * it should return ssl = NULL */ int DetectSslVersionTestParse02(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("2.5"); if (ssl == NULL) { DetectSslVersionFree(ssl); return 1; } return 0; }
/** * \test DetectSslVersionTestParse01 is a test to make sure that we parse the * "ssl_version" option correctly when given valid ssl_version option */ int DetectSslVersionTestParse01(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("SSlv3"); if (ssl != NULL && ssl->data[SSLv3].ver == SSL_VERSION_3) { DetectSslVersionFree(ssl); return 1; } return 0; }
/** * \test DetectSslVersionTestParse03 is a test to make sure that we parse the * "ssl_version" options correctly when given valid ssl_version options */ static int DetectSslVersionTestParse03(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("SSlv3,tls1.0, !tls1.2"); FAIL_IF_NULL(ssl); FAIL_IF_NOT(ssl->data[SSLv3].ver == SSL_VERSION_3); FAIL_IF_NOT(ssl->data[TLS10].ver == TLS_VERSION_10); FAIL_IF_NOT(ssl->data[TLS12].ver == TLS_VERSION_12); FAIL_IF_NOT(ssl->data[TLS12].flags & DETECT_SSL_VERSION_NEGATED); DetectSslVersionFree(ssl); PASS; }
/** * \test DetectSslVersionTestParse03 is a test to make sure that we parse the * "ssl_version" options correctly when given valid ssl_version options */ int DetectSslVersionTestParse03(void) { DetectSslVersionData *ssl = NULL; ssl = DetectSslVersionParse("SSlv3,tls1.0, !tls1.2"); if (ssl != NULL && ssl->data[SSLv3].ver == SSL_VERSION_3 && ssl->data[TLS10].ver == TLS_VERSION_10 && ssl->data[TLS12].ver == TLS_VERSION_12 && ssl->data[TLS12].flags & DETECT_SSL_VERSION_NEGATED) { DetectSslVersionFree(ssl); return 1; } return 0; }
/** * \brief This function is used to parse ssl_version data passed via * keyword: "ssl_version" * * \param str Pointer to the user provided options * * \retval ssl pointer to DetectSslVersionData on success * \retval NULL on failure */ static DetectSslVersionData *DetectSslVersionParse(const char *str) { DetectSslVersionData *ssl = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); if (ret < 1 || ret > 5) { SCLogError(SC_ERR_PCRE_MATCH, "invalid ssl_version option"); goto error; } if (ret > 1) { const char *str_ptr; char *orig; uint8_t found = 0, neg = 0; char *tmp_str; /* We have a correct ssl_version options */ ssl = SCCalloc(1, sizeof (DetectSslVersionData)); if (unlikely(ssl == NULL)) goto error; int i; for (i = 1; i < ret; i++) { res = pcre_get_substring((char *) str, ov, MAX_SUBSTRINGS, i, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); if (found == 0) goto error; break; } orig = SCStrdup((char*) str_ptr); if (unlikely(orig == NULL)) { goto error; } tmp_str = orig; /* Let's see if we need to scape "'s */ if (tmp_str[0] == '"') { tmp_str[strlen(tmp_str) - 1] = '\0'; tmp_str += 1; } if (tmp_str[0] == '!') { neg = 1; tmp_str++; } if (strncasecmp("sslv2", tmp_str, 5) == 0) { ssl->data[SSLv2].ver = SSL_VERSION_2; if (neg == 1) ssl->data[SSLv2].flags |= DETECT_SSL_VERSION_NEGATED; } else if (strncasecmp("sslv3", tmp_str, 5) == 0) { ssl->data[SSLv3].ver = SSL_VERSION_3; if (neg == 1) ssl->data[SSLv3].flags |= DETECT_SSL_VERSION_NEGATED; } else if (strncasecmp("tls1.0", tmp_str, 6) == 0) { ssl->data[TLS10].ver = TLS_VERSION_10; if (neg == 1) ssl->data[TLS10].flags |= DETECT_SSL_VERSION_NEGATED; } else if (strncasecmp("tls1.1", tmp_str, 6) == 0) { ssl->data[TLS11].ver = TLS_VERSION_11; if (neg == 1) ssl->data[TLS11].flags |= DETECT_SSL_VERSION_NEGATED; } else if (strncasecmp("tls1.2", tmp_str, 6) == 0) { ssl->data[TLS12].ver = TLS_VERSION_12; if (neg == 1) ssl->data[TLS12].flags |= DETECT_SSL_VERSION_NEGATED; } else if (strcmp(tmp_str, "") == 0) { SCFree(orig); if (found == 0) goto error; break; } else { SCLogError(SC_ERR_INVALID_VALUE, "Invalid value"); SCFree(orig); goto error; } found = 1; neg = 0; SCFree(orig); pcre_free_substring(str_ptr); } } return ssl; error: if (ssl != NULL) DetectSslVersionFree(ssl); return NULL; }