示例#1
0
文件: mpool.c 项目: OPSF/uClinux
char *cli_mpool_virname(mpool_t *mp, const char *virname, unsigned int official) {
  char *newname, *pt;
  if(!virname)
    return NULL;

  if((pt = strchr(virname, ' ')))
      if((pt = strstr(pt, " (Clam)")))
	  *pt='\0';

  if(!virname[0]) {
    cli_errmsg("cli_virname: Empty virus name\n");
    return NULL;
  }

  if(official)
    return cli_mpool_strdup(mp, virname);

  newname = (char *)mpool_malloc(mp, strlen(virname) + 11 + 1);
  if(!newname) {
    cli_errmsg("cli_virname: Can't allocate memory for newname\n");
    return NULL;
  }
  sprintf(newname, "%s.UNOFFICIAL", virname);
  return newname;
}
示例#2
0
int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *trigger, const char *pattern, const char *cflags, const char *offset, const uint32_t *lsigid, unsigned int options)
{
    struct cli_pcre_meta **newmetatable = NULL, *pm = NULL;
    uint32_t pcre_count;
    const char *opt;
    int ret = CL_SUCCESS, rssigs;

    if (!root || !trigger || !pattern || !offset) {
        cli_errmsg("cli_pcre_addpatt: NULL root or NULL trigger or NULL pattern or NULL offset\n");
        return CL_ENULLARG;
    }

    /* TODO: trigger and regex checking (backreference limitations?) (control pattern limitations?) */
    /* cli_ac_chklsig will fail a empty trigger; empty patterns can cause an infinite loop */
    if (*trigger == '\0' || *pattern == '\0') {
        cli_errmsg("cli_pcre_addpatt: trigger or pattern cannot be an empty string\n");
        return CL_EMALFDB;
    }
    if (cflags && *cflags == '\0') {
        cflags = NULL;
    }

    if (lsigid)
        pm_dbgmsg("cli_pcre_addpatt: Adding /%s/%s%s triggered on (%s) as subsig %d for lsigid %d\n", 
                  pattern, cflags ? " with flags " : "", cflags ? cflags : "", trigger, lsigid[1], lsigid[0]);
    else
        pm_dbgmsg("cli_pcre_addpatt: Adding /%s/%s%s triggered on (%s) [no lsigid]\n",
                  pattern, cflags ? " with flags " : "", cflags ? cflags : "", trigger);

#ifdef PCRE_BYPASS
    /* check for trigger bypass */
    if (strcmp(trigger, PCRE_BYPASS)) {
#endif
        /* validate the lsig trigger */
        rssigs = cli_ac_chklsig(trigger, trigger + strlen(trigger), NULL, NULL, NULL, 1);
        if(rssigs == -1) {
            cli_errmsg("cli_pcre_addpatt: regex subsig /%s/ is missing a valid logical trigger\n", pattern);
            return CL_EMALFDB;
        }

        if (lsigid) {
            if (rssigs > lsigid[1]) {
                cli_errmsg("cli_pcre_addpatt: regex subsig %d logical trigger refers to subsequent subsig %d\n", lsigid[1], rssigs);
                return CL_EMALFDB;
            }
            if (rssigs == lsigid[1]) {
                cli_errmsg("cli_pcre_addpatt: regex subsig %d logical trigger is self-referential\n", lsigid[1]);
                return CL_EMALFDB;
            }
        }
        else {
            cli_dbgmsg("cli_pcre_addpatt: regex subsig is missing lsigid data\n");
        }
#ifdef PCRE_BYPASS
    }
#endif

    /* allocating entries */
    pm = (struct cli_pcre_meta *)mpool_calloc(root->mempool, 1, sizeof(*pm));
    if (!pm) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for new pcre meta\n");
        return CL_EMEM;
    }

    pm->trigger = cli_mpool_strdup(root->mempool, trigger);
    if (!pm->trigger) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for trigger string\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    pm->virname = (char *)cli_mpool_virname(root->mempool, virname, options & CL_DB_OFFICIAL);
    if(!pm->virname) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for virname or NULL virname\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    if (lsigid) {
        root->ac_lsigtable[lsigid[0]]->virname = pm->virname;

        pm->lsigid[0] = 1;
        pm->lsigid[1] = lsigid[0];
        pm->lsigid[2] = lsigid[1];
    }
    else {
        /* sigtool */
        pm->lsigid[0] = 0;
    }

    pm->pdata.expression = strdup(pattern);
    if (!pm->pdata.expression) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for expression\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    /* offset parsing and usage, similar to cli_ac_addsig */
    /* relative and type-specific offsets handled during scan */
    ret = cli_caloff(offset, NULL, root->type, pm->offdata, &(pm->offset_min), &(pm->offset_max));
    if (ret != CL_SUCCESS) {
        cli_errmsg("cli_pcre_addpatt: cannot calculate offset data: %s for pattern: %s\n", offset, pattern);
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return ret;
    }
    if(pm->offdata[0] != CLI_OFF_ANY) {
        if(pm->offdata[0] == CLI_OFF_ABSOLUTE)
            root->pcre_absoff_num++;
        else
            root->pcre_reloff_num++;
    }

    /* parse and add options, also totally not from snort */
    if (cflags) {
        opt = cflags;

        /* cli_pcre_addoptions handles pcre specific options */
        while (cli_pcre_addoptions(&(pm->pdata), &opt, 0) != CL_SUCCESS) {
            /* handle matcher specific options here */
            switch (*opt) {
            case 'g':  pm->flags |= CLI_PCRE_GLOBAL;            break;
            case 'r':  pm->flags |= CLI_PCRE_ROLLING;           break;
            case 'e':  pm->flags |= CLI_PCRE_ENCOMPASS;         break;
            default:
                cli_errmsg("cli_pcre_addpatt: unknown/extra pcre option encountered %c\n", *opt);
                cli_pcre_freemeta(root, pm);
                mpool_free(root->mempool, pm);
                return CL_EMALFDB;
            }
            opt++;
        }

        if (pm->flags) {
            pm_dbgmsg("Matcher:  %s%s%s\n",
                      pm->flags & CLI_PCRE_GLOBAL ? "CLAMAV_GLOBAL " : "",
                      pm->flags & CLI_PCRE_ROLLING ? "CLAMAV_ROLLING " : "",
                      pm->flags & CLI_PCRE_ENCOMPASS ? "CLAMAV_ENCOMPASS " : "");
        }
        else
            pm_dbgmsg("Matcher:  NONE\n");

        if (pm->pdata.options) {
#if USING_PCRE2
            pm_dbgmsg("Compiler: %s%s%s%s%s%s%s\n",
                      pm->pdata.options & PCRE2_CASELESS ? "PCRE2_CASELESS " : "",
                      pm->pdata.options & PCRE2_DOTALL ? "PCRE2_DOTALL " : "",
                      pm->pdata.options & PCRE2_MULTILINE ? "PCRE2_MULTILINE " : "",
                      pm->pdata.options & PCRE2_EXTENDED ? "PCRE2_EXTENDED " : "",

                      pm->pdata.options & PCRE2_ANCHORED ? "PCRE2_ANCHORED " : "",
                      pm->pdata.options & PCRE2_DOLLAR_ENDONLY ? "PCRE2_DOLLAR_ENDONLY " : "",
                      pm->pdata.options & PCRE2_UNGREEDY ? "PCRE2_UNGREEDY " : "");
#else
            pm_dbgmsg("Compiler: %s%s%s%s%s%s%s\n",
                      pm->pdata.options & PCRE_CASELESS ? "PCRE_CASELESS " : "",
                      pm->pdata.options & PCRE_DOTALL ? "PCRE_DOTALL " : "",
                      pm->pdata.options & PCRE_MULTILINE ? "PCRE_MULTILINE " : "",
                      pm->pdata.options & PCRE_EXTENDED ? "PCRE_EXTENDED " : "",

                      pm->pdata.options & PCRE_ANCHORED ? "PCRE_ANCHORED " : "",
                      pm->pdata.options & PCRE_DOLLAR_ENDONLY ? "PCRE_DOLLAR_ENDONLY " : "",
                      pm->pdata.options & PCRE_UNGREEDY ? "PCRE_UNGREEDY " : "");
#endif
        }
        else
            pm_dbgmsg("Compiler: NONE\n");
    }

    /* add metadata to the performance tracker */
    if (options & CL_DB_PCRE_STATS)
        pcre_perf_events_init(pm, virname);

    /* add pcre data to root after reallocation */
    pcre_count = root->pcre_metas+1;
    newmetatable = (struct cli_pcre_meta **)mpool_realloc(root->mempool, root->pcre_metatable,
                                         pcre_count * sizeof(struct cli_pcre_meta *));
    if (!newmetatable) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for new pcre meta table\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    newmetatable[pcre_count-1] = pm;
    root->pcre_metatable = newmetatable;

    root->pcre_metas = pcre_count;

    return CL_SUCCESS;
}