Beispiel #1
0
int cli_process_ooxml(cli_ctx *ctx)
{
#if HAVE_LIBXML2 && HAVE_JSON
    uint32_t loff = 0;

    cli_dbgmsg("in cli_processooxml\n");
    if (!ctx) {
        return CL_ENULLARG;
    }

    /* find "[Content Types].xml" */
    if (unzip_search(ctx, "[Content_Types].xml", 18, &loff) != CL_VIRUS) {
        cli_dbgmsg("cli_process_ooxml: failed to find ""[Content_Types].xml""!\n");
        return CL_EFORMAT;
    }
    cli_dbgmsg("cli_process_ooxml: found ""[Content_Types].xml"" @ %x\n", loff);

    return unzip_single_internal(ctx, loff, ooxml_content_cb);
#else
    cli_dbgmsg("in cli_processooxml\n");
#if !HAVE_LIBXML2
    cli_dbgmsg("cli_process_ooxml: libxml2 needs to enabled!");
#endif
#if !HAVE_JSON
    cli_dbgmsg("cli_process_ooxml: libjson needs to enabled!");
#endif
    return CL_SUCCESS;
#endif
}
Beispiel #2
0
int cli_process_ooxml(cli_ctx *ctx)
{
#if HAVE_LIBXML2 && HAVE_JSON
    uint32_t loff = 0;
    int tmp = CL_SUCCESS;

    cli_dbgmsg("in cli_process_ooxml\n");
    if (!ctx) {
        return CL_ENULLARG;
    }

    /* find "[Content Types].xml" */
    tmp = unzip_search_single(ctx, "[Content_Types].xml", 18, &loff);
    if (tmp == CL_ETIMEOUT) {
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
        return CL_ETIMEOUT;
    }
    else if (tmp != CL_VIRUS) {
        cli_dbgmsg("cli_process_ooxml: failed to find ""[Content_Types].xml""!\n");
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_CONTENT_TYPES");
        return CL_EFORMAT;
    }
    cli_dbgmsg("cli_process_ooxml: found ""[Content_Types].xml"" @ %x\n", loff);

    tmp = unzip_single_internal(ctx, loff, ooxml_content_cb);
    if (tmp == CL_ETIMEOUT)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
    else if (tmp == CL_EMEM)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_OUTOFMEM");
    else if (tmp == CL_EMAXSIZE)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXSIZE");
    else if (tmp == CL_EMAXFILES)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXFILES");

    return tmp;
#else
    UNUSEDPARAM(ctx);
    cli_dbgmsg("in cli_process_ooxml\n");
#if !HAVE_LIBXML2
    cli_dbgmsg("cli_process_ooxml: libxml2 needs to enabled!\n");
#endif
#if !HAVE_JSON
    cli_dbgmsg("cli_process_ooxml: libjson needs to enabled!\n");
#endif
    return CL_SUCCESS;
#endif
}
Beispiel #3
0
static int ooxml_content_cb(int fd, cli_ctx *ctx)
{
    int ret = CL_SUCCESS, tmp, toval = 0, state;
    int core=0, extn=0, cust=0, dsig=0;
    int mcore=0, mextn=0, mcust=0;
    const xmlChar *name, *value, *CT, *PN;
    xmlTextReaderPtr reader = NULL;
    uint32_t loff;

    unsigned long sav_scansize = ctx->scansize;
    unsigned int sav_scannedfiles = ctx->scannedfiles;

    cli_dbgmsg("in ooxml_content_cb\n");

    /* perform engine limit checks in temporary tracking session */
    ret = ooxml_updatelimits(fd, ctx);
    if (ret != CL_CLEAN)
        return ret;

    /* apply a reader to the document */
    reader = xmlReaderForFd(fd, "[Content_Types].xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS);
    if (reader == NULL) {
        cli_dbgmsg("ooxml_content_cb: xmlReaderForFd error for ""[Content_Types].xml""\n");
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_XML_READER_FD");

        ctx->scansize = sav_scansize;
        ctx->scannedfiles = sav_scannedfiles;
        return CL_SUCCESS; // libxml2 failed!
    }

    /* locate core-properties, extended-properties, and custom-properties (optional) */
    while ((state = xmlTextReaderRead(reader)) == 1) {
        if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
            ret = CL_ETIMEOUT;
            goto ooxml_content_exit;
        }

        name = xmlTextReaderConstLocalName(reader);
        if (name == NULL) continue;

        if (strcmp((const char *)name, "Override")) continue;

        if (xmlTextReaderHasAttributes(reader) != 1) continue;

        CT = PN = NULL;
        while (xmlTextReaderMoveToNextAttribute(reader) == 1) {
            name = xmlTextReaderConstLocalName(reader);
            value = xmlTextReaderConstValue(reader);
            if (name == NULL || value == NULL) continue;

            if (!xmlStrcmp(name, (const xmlChar *)"ContentType")) {
                CT = value;
            }
            else if (!xmlStrcmp(name, (const xmlChar *)"PartName")) {
                PN = value;
            }

            cli_dbgmsg("%s: %s\n", name, value);
        }

        if (!CT && !PN) continue;

        if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.core-properties+xml")) {
            /* default: /docProps/core.xml*/
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
            if (tmp == CL_ETIMEOUT) {
                ret = tmp;
            }
            else if (tmp != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
                mcore++;
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
                if (!core) {
                    tmp = unzip_single_internal(ctx, loff, ooxml_core_cb);
                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
                        ret = tmp;
                    }
                }
                core++;
            }
        }
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
            /* default: /docProps/app.xml */
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
            if (tmp == CL_ETIMEOUT) {
                ret = tmp;
            }
            else if (tmp != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
                mextn++;
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
                if (!extn) {
                    tmp = unzip_single_internal(ctx, loff, ooxml_extn_cb);
                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
                        ret = tmp;
                    }
                }
                extn++;
            }
        }
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
            /* default: /docProps/custom.xml */
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
            if (tmp == CL_ETIMEOUT) {
                ret = tmp;
            }
            else if (tmp != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
                mcust++;
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
                /* custom properties are not parsed */
                cust++;
            }
        }
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
            dsig++;
        }

        if (ret != CL_SUCCESS)
            goto ooxml_content_exit;
    }

 ooxml_content_exit:
    if (core) {
        cli_jsonint(ctx->wrkproperty, "CorePropertiesFileCount", core);
        if (core > 1)
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CORE_PROPFILES");
    }
    else if (!mcore)
        cli_dbgmsg("cli_process_ooxml: file does not contain core properties file\n");
    if (mcore) {
        cli_jsonint(ctx->wrkproperty, "CorePropertiesMissingFileCount", mcore);
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CORE_PROPFILES");
    }

    if (extn) {
        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesFileCount", extn);
        if (extn > 1)
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_EXTN_PROPFILES");
    }
    else if (!mextn)
        cli_dbgmsg("cli_process_ooxml: file does not contain extended properties file\n");
    if (mextn) {
        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesMissingFileCount", mextn);
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_EXTN_PROPFILES");
    }

    if (cust) {
        cli_jsonint(ctx->wrkproperty, "CustomPropertiesFileCount", cust);
        if (cust > 1)
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CUSTOM_PROPFILES");
    }
    else if (!mcust)
        cli_dbgmsg("cli_process_ooxml: file does not contain custom properties file\n");
    if (mcust) {
        cli_jsonint(ctx->wrkproperty, "CustomPropertiesMissingFileCount", mcust);
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CUST_PROPFILES");
    }

    if (dsig) {
        cli_jsonint(ctx->wrkproperty, "DigitalSignaturesCount", dsig);
    }

    /* restore the engine tracking limits; resets session limit tracking */
    ctx->scansize = sav_scansize;
    ctx->scannedfiles = sav_scannedfiles;

    xmlTextReaderClose(reader);
    xmlFreeTextReader(reader);
    return ret;
}
Beispiel #4
0
int cli_process_ooxml(cli_ctx *ctx, int type)
{
#if HAVE_LIBXML2 && HAVE_JSON
    uint32_t loff = 0;
    int ret = CL_SUCCESS;

    cli_dbgmsg("in cli_process_ooxml\n");
    if (!ctx) {
        return CL_ENULLARG;
    }

    if (type == CL_TYPE_OOXML_HWP) {
        /* two files: version.xml and Contents/content.hpf */
        ret = unzip_search_single(ctx, "version.xml", 11, &loff);
        if (ret == CL_ETIMEOUT) {
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
            return CL_ETIMEOUT;
        }
        else if (ret != CL_VIRUS) {
            cli_dbgmsg("cli_process_ooxml: failed to find ""version.xml""!\n");
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_HWP_VERSION");
            return CL_EFORMAT;
        }
        ret = unzip_single_internal(ctx, loff, ooxml_hwp_cb);

        if (ret == CL_SUCCESS) {
            ret = unzip_search_single(ctx, "Contents/content.hpf", 20, &loff);
            if (ret == CL_ETIMEOUT) {
                cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
                return CL_ETIMEOUT;
            }
            else if (ret != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find ""Contents/content.hpf""!\n");
                cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_HWP_CONTENT");
                return CL_EFORMAT;
            }
            ret = unzip_single_internal(ctx, loff, ooxml_hwp_cb);
        }
    } else {
        /* find "[Content Types].xml" */
        ret = unzip_search_single(ctx, "[Content_Types].xml", 19, &loff);
        if (ret == CL_ETIMEOUT) {
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
            return CL_ETIMEOUT;
        }
        else if (ret != CL_VIRUS) {
            cli_dbgmsg("cli_process_ooxml: failed to find ""[Content_Types].xml""!\n");
            cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_CONTENT_TYPES");
            return CL_EFORMAT;
        }
        cli_dbgmsg("cli_process_ooxml: found ""[Content_Types].xml"" @ %x\n", loff);

        ret = unzip_single_internal(ctx, loff, ooxml_content_cb);
    }

    if (ret == CL_ETIMEOUT)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
    else if (ret == CL_EMEM)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_OUTOFMEM");
    else if (ret == CL_EMAXSIZE)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXSIZE");
    else if (ret == CL_EMAXFILES)
        cli_json_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXFILES");

    return ret;
#else
    UNUSEDPARAM(ctx);
    cli_dbgmsg("in cli_process_ooxml\n");
#if !HAVE_LIBXML2
    cli_dbgmsg("cli_process_ooxml: libxml2 needs to enabled!\n");
#endif
#if !HAVE_JSON
    cli_dbgmsg("cli_process_ooxml: libjson needs to enabled!\n");
#endif
    return CL_SUCCESS;
#endif
}
Beispiel #5
0
int cli_unzip_single(cli_ctx *ctx, off_t lhoffl) {
    return unzip_single_internal(ctx, lhoffl, zip_scan_cb);
}
Beispiel #6
0
static int ooxml_content_cb(int fd, cli_ctx *ctx)
{
    int ret = CL_SUCCESS;
    int core=0, extn=0, cust=0, dsig=0;
    const xmlChar *name, *value, *CT, *PN;
    xmlTextReaderPtr reader = NULL;
    uint32_t loff;

    cli_dbgmsg("in ooxml_content_cb\n");

    reader = xmlReaderForFd(fd, "[Content_Types].xml", NULL, 0);
    if (reader == NULL) {
        cli_dbgmsg("ooxml_content_cb: xmlReaderForFd error for ""[Content_Types].xml""\n");
        return CL_SUCCESS; // libxml2 failed!
    }

    /* locate core-properties, extended-properties, and custom-properties (optional)  */
    while (xmlTextReaderRead(reader) == 1) {
        name = xmlTextReaderConstLocalName(reader);
        if (name == NULL) continue;

        if (strcmp(name, "Override")) continue;

        if (!xmlTextReaderHasAttributes(reader)) continue;

        CT = NULL; PN = NULL;
        while (xmlTextReaderMoveToNextAttribute(reader) == 1) {
            name = xmlTextReaderConstLocalName(reader);
            value = xmlTextReaderConstValue(reader);
            if (name == NULL || value == NULL) continue;

            if (!xmlStrcmp(name, "ContentType")) {
                CT = value;
            }
            else if (!xmlStrcmp(name, "PartName")) {
                PN = value;
            }

            cli_dbgmsg("%s: %s\n", name, value);
        }

        if (!CT && !PN) continue;

        if (!core && !xmlStrcmp(CT, "application/vnd.openxmlformats-package.core-properties+xml")) {
            /* default: /docProps/core.xml*/
            if (unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff) != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
                ret = unzip_single_internal(ctx, loff, ooxml_core_cb);
            }
            core = 1;
        }
        else if (!extn && !xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
            /* default: /docProps/app.xml */
            if (unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff) != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
                ret = unzip_single_internal(ctx, loff, ooxml_extn_cb);
            }
            extn = 1;
        }
        else if (!cust && !xmlStrcmp(CT, "application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
            /* default: /docProps/custom.xml */
            if (unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff) != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
                /* custom properties ignored for now */
                cli_jsonbool(ctx->wrkproperty, "CustomProperties", 1);
                //ret = unzip_single_internal(ctx, loff, ooxml_cust_cb);
            }
            cust = 1;
        }
        else if (!dsig && !xmlStrcmp(CT, "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
            if (unzip_search(ctx, PN+1, xmlStrlen(PN)-1, &loff) != CL_VIRUS) {
                cli_dbgmsg("cli_process_ooxml: failed to find digital signature file \"%s\"!\n", PN);
            }
            else {
                cli_dbgmsg("ooxml_content_cb: found digital signature file \"%s\" @ %x\n", PN, loff);
                /* digital signatures ignored for now */
                cli_jsonbool(ctx->wrkproperty, "DigitalSignatures", 1);
                //ret = unzip_single_internal(ctx, loff, ooxml_dsig_cb);
            }
            dsig = 1;
        }

        if (ret != CL_SUCCESS)
            goto ooxml_content_exit;
    }

    if (!core) {
        cli_dbgmsg("cli_process_ooxml: file does not contain core properties file\n");
    }
    if (!extn) {
        cli_dbgmsg("cli_process_ooxml: file does not contain extended properties file\n");
    }
    if (!cust) {
        cli_dbgmsg("cli_process_ooxml: file does not contain custom properties file\n");
    }

 ooxml_content_exit:
    xmlTextReaderClose(reader);
    xmlFreeTextReader(reader);
    return ret;
}