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 }
int cli_ooxml_filetype(cli_ctx *ctx, fmap_t *map) { struct zip_requests requests; int ret; memset(&requests, 0, sizeof(struct zip_requests)); if ((ret = unzip_search_add(&requests, "xl/", 3)) != CL_SUCCESS) { return CL_SUCCESS; } if ((ret = unzip_search_add(&requests, "ppt/", 4)) != CL_SUCCESS) { return CL_SUCCESS; } if ((ret = unzip_search_add(&requests, "word/", 5)) != CL_SUCCESS) { return CL_SUCCESS; } if ((ret = unzip_search(ctx, map, &requests)) == CL_VIRUS) { switch (requests.found) { case 0: return CL_TYPE_OOXML_XL; case 1: return CL_TYPE_OOXML_PPT; case 2: return CL_TYPE_OOXML_WORD; default: return CL_SUCCESS; } } return CL_SUCCESS; }
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; }