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_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 }
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; }
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 }
int cli_unzip_single(cli_ctx *ctx, off_t lhoffl) { return unzip_single_internal(ctx, lhoffl, zip_scan_cb); }
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; }