/** * \brief This function is used to parse fileet * * \param str Pointer to the fileext value string * * \retval pointer to DetectFileextData on success * \retval NULL on failure */ static DetectFileextData *DetectFileextParse (const char *str, bool negate) { DetectFileextData *fileext = NULL; /* We have a correct filename option */ fileext = SCMalloc(sizeof(DetectFileextData)); if (unlikely(fileext == NULL)) goto error; memset(fileext, 0x00, sizeof(DetectFileextData)); if (DetectContentDataParse("fileext", str, &fileext->ext, &fileext->len) == -1) { goto error; } uint16_t u; for (u = 0; u < fileext->len; u++) fileext->ext[u] = tolower(fileext->ext[u]); if (negate) { fileext->flags |= DETECT_CONTENT_NEGATED; } SCLogDebug("flags %02X", fileext->flags); if (fileext->flags & DETECT_CONTENT_NEGATED) { SCLogDebug("negated fileext"); } #ifdef DEBUG if (SCLogDebugEnabled()) { char *ext = SCMalloc(fileext->len + 1); if (ext != NULL) { memcpy(ext, fileext->ext, fileext->len); ext[fileext->len] = '\0'; SCLogDebug("will look for fileext %s", ext); } } #endif return fileext; error: if (fileext != NULL) DetectFileextFree(fileext); return NULL; }
/** * \brief Parse the filename keyword * * \param idstr Pointer to the user provided option * * \retval filename pointer to DetectFilenameData on success * \retval NULL on failure */ static DetectFilenameData *DetectFilenameParse (char *str) { DetectFilenameData *filename = NULL; /* We have a correct filename option */ filename = SCMalloc(sizeof(DetectFilenameData)); if (unlikely(filename == NULL)) goto error; memset(filename, 0x00, sizeof(DetectFilenameData)); if (DetectContentDataParse ("filename", str, &filename->name, &filename->len, &filename->flags) == -1) { goto error; } filename->bm_ctx = BoyerMooreCtxInit(filename->name, filename->len); if (filename->bm_ctx == NULL) { goto error; } SCLogDebug("flags %02X", filename->flags); if (filename->flags & DETECT_CONTENT_NEGATED) { SCLogDebug("negated filename"); } BoyerMooreCtxToNocase(filename->bm_ctx, filename->name, filename->len); #ifdef DEBUG if (SCLogDebugEnabled()) { char *name = SCMalloc(filename->len + 1); if (name != NULL) { memcpy(name, filename->name, filename->len); name[filename->len] = '\0'; SCLogDebug("will look for filename %s", name); } } #endif return filename; error: if (filename != NULL) DetectFilenameFree(filename); return NULL; }
int DetectReplaceSetup(DetectEngineCtx *de_ctx, Signature *s, char *replacestr) { uint8_t *content = NULL; uint16_t len = 0; uint32_t flags = 0; SigMatch *pm = NULL; DetectContentData *ud = NULL; int ret = DetectContentDataParse("replace", replacestr, &content, &len, &flags); if (ret == -1) goto error; if (flags & DETECT_CONTENT_NEGATED) { SCLogError(SC_ERR_INVALID_VALUE, "Can't negate replacement string: %s", replacestr); goto error; } switch (run_mode) { case RUNMODE_NFQ: case RUNMODE_IPFW: break; default: SCLogWarning(SC_ERR_RUNMODE, "Can't use 'replace' keyword in non IPS mode: %s", s->sig_str); /* this is a success, having the alert is interesting */ return 0; } /* add to the latest "content" keyword from either dmatch or pmatch */ pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); if (pm == NULL) { SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "replace needs" "preceding content option for raw sig"); SCFree(content); return -1; } /* we can remove this switch now with the unified structure */ ud = (DetectContentData *)pm->ctx; if (ud == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument"); SCFree(content); return -1; } if (ud->flags & DETECT_CONTENT_NEGATED) { SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " "negated keyword set along with a replacement"); goto error; } if (ud->content_len != len) { SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a content " "length different from replace length"); goto error; } ud->replace = SCMalloc(len); if (ud->replace == NULL) { goto error; } memcpy(ud->replace, content, len); ud->replace_len = len; ud->flags |= DETECT_CONTENT_REPLACE; /* want packet matching only won't be able to replace data with * a flow. */ s->flags |= SIG_FLAG_REQUIRE_PACKET; SCFree(content); return 0; error: SCFree(content); return -1; }
static int DetectFlowvarSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) { DetectFlowvarData *fd = NULL; SigMatch *sm = NULL; char *varname = NULL, *varcontent = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; const char *str_ptr; uint8_t *content = NULL; uint16_t contentlen = 0; uint32_t contentflags = 0; ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 3) { SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowvar.", rawstr); return -1; } res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varname = (char *)str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varcontent = (char *)str_ptr; res = DetectContentDataParse("flowvar", varcontent, &content, &contentlen, &contentflags); if (res == -1) goto error; fd = SCMalloc(sizeof(DetectFlowvarData)); if (unlikely(fd == NULL)) goto error; memset(fd, 0x00, sizeof(*fd)); fd->content = SCMalloc(contentlen); if (unlikely(fd->content == NULL)) goto error; memcpy(fd->content, content, contentlen); fd->content_len = contentlen; fd->flags = contentflags; fd->name = SCStrdup(varname); if (unlikely(fd->name == NULL)) goto error; fd->idx = VariableNameGetIdx(de_ctx, varname, VAR_TYPE_FLOW_VAR); /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (unlikely(sm == NULL)) goto error; sm->type = DETECT_FLOWVAR; sm->ctx = (SigMatchCtx *)fd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); SCFree(content); return 0; error: if (fd != NULL) DetectFlowvarDataFree(fd); if (sm != NULL) SCFree(sm); if (content != NULL) SCFree(content); return -1; }
static int DetectPktvarSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) { char *varname = NULL, *varcontent = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; uint8_t *content = NULL; uint16_t len = 0; ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 3) { SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for pktvar.", rawstr); return -1; } const char *str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varname = (char *)str_ptr; res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); return -1; } varcontent = (char *)str_ptr; SCLogDebug("varname '%s', varcontent '%s'", varname, varcontent); char *parse_content; if (strlen(varcontent) >= 2 && varcontent[0] == '"' && varcontent[strlen(varcontent) - 1] == '"') { parse_content = varcontent + 1; varcontent[strlen(varcontent) - 1] = '\0'; } else { parse_content = varcontent; } ret = DetectContentDataParse("pktvar", parse_content, &content, &len); if (ret == -1 || content == NULL) { pcre_free(varname); pcre_free(varcontent); return -1; } DetectPktvarData *cd = SCCalloc(1, sizeof(DetectPktvarData)); if (unlikely(cd == NULL)) { pcre_free(varname); pcre_free(varcontent); SCFree(content); return -1; } cd->content = content; cd->content_len = len; cd->id = VarNameStoreSetupAdd(varname, VAR_TYPE_PKT_VAR); pcre_free(varname); pcre_free(varcontent); /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ SigMatch *sm = SigMatchAlloc(); if (unlikely(sm == NULL)) { SCFree(cd->content); SCFree(cd); return -1; } sm->type = DETECT_PKTVAR; sm->ctx = (SigMatchCtx *)cd; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); return 0; }