Browse code

binhex, pdf, unzip_single to fmap

aCaB authored on 2009/08/31 12:37:43
Showing 8 changed files
... ...
@@ -110,20 +110,15 @@ static	char	const	rcsid[] = "$Id: binhex.c,v 1.23 2007/02/12 20:46:08 njh Exp $"
110 110
 #include "fmap.h"
111 111
 
112 112
 int
113
-cli_binhex(const char *dir, int desc)
113
+cli_binhex(const char *dir, struct F_MAP *map)
114 114
 {
115
-	struct stat statb;
116 115
 	char *buf, *start, *line;
117 116
 	size_t size;
118 117
 	long bytesleft;
119 118
 	message *m;
120 119
 	fileblob *fb;
121
-	struct F_MAP *map;
122 120
 
123
-	if(fstat(desc, &statb) < 0)
124
-		return CL_EOPEN;
125
-
126
-	size = (size_t)statb.st_size;
121
+	size = (size_t)map->len;
127 122
 
128 123
 	if(size == 0)
129 124
 		return CL_CLEAN;
... ...
@@ -131,10 +126,6 @@ cli_binhex(const char *dir, int desc)
131 131
 	m = messageCreate();
132 132
 	if(m == NULL)
133 133
 		return CL_EMEM;
134
-	if(!(map = fmap(desc, 0, size))) {
135
-		messageDestroy(m);
136
-		return CL_EMAP;
137
-	}
138 134
 
139 135
 	start = buf = fmap_need_off_once(map, 0, size);
140 136
 	if(!buf) {
... ...
@@ -181,7 +172,6 @@ cli_binhex(const char *dir, int desc)
181 181
 		buf = ++ptr;
182 182
 		bytesleft--;
183 183
 	}
184
-	fmunmap(map);
185 184
 
186 185
 	if(line)
187 186
 		free(line);
... ...
@@ -33,6 +33,6 @@
33 33
 #ifndef __BINHEX_H
34 34
 #define __BINHEX_H
35 35
 
36
-int	cli_binhex(const char *dir, int desc);
36
+int cli_binhex(const char *dir, struct F_MAP *map);
37 37
 
38 38
 #endif
... ...
@@ -600,7 +600,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
600 600
 	    }
601 601
 
602 602
 	    if(ctx->engine->md5_hdb)
603
-		cli_md5_update(&md5ctx, buff + maxpatlen * (offset!=0), bytes);
603
+		cli_md5_update(&md5ctx, buff + maxpatlen * (offset!=0), bytes - maxpatlen * (offset!=0));
604 604
 	}
605 605
 
606 606
 	if(bytes < SCANBUFF) break;
... ...
@@ -70,7 +70,7 @@ static	const	char	*pdf_nextlinestart(const char *ptr, size_t len);
70 70
 static	const	char	*pdf_nextobject(const char *ptr, size_t len);
71 71
 
72 72
 int
73
-cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
73
+cli_pdf(const char *dir, cli_ctx *ctx, off_t offset)
74 74
 {
75 75
 	off_t size;	/* total number of bytes in the file */
76 76
 	off_t bytesleft, trailerlength;
... ...
@@ -81,27 +81,16 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
81 81
 	table_t *md5table;
82 82
 	int printed_predictor_message, printed_embedded_font_message, rc;
83 83
 	unsigned int files;
84
-	struct stat statb;
85
-	struct F_MAP *map;
84
+	struct F_MAP *map = *ctx->fmap;
86 85
 	int opt_failed = 0;
87 86
 
88 87
 	cli_dbgmsg("in cli_pdf(%s)\n", dir);
89 88
 
90
-	if(fstat(desc, &statb) < 0) {
91
-		cli_errmsg("cli_pdf: fstat() failed\n");
92
-		return CL_EOPEN;
93
-	}
94
-
95
-	size = statb.st_size - offset;
89
+	size = map->len - offset;
96 90
 
97 91
 	if(size <= 7)	/* doesn't even include the file header */
98 92
 		return CL_CLEAN;
99 93
 
100
-	if(!(map = fmap(desc, offset, size))) {
101
-	    cli_errmsg("cli_pdf: mmap() failed\n");
102
-	    return CL_EMAP;
103
-	}
104
-	
105 94
 	p = buf = fmap_need_off(map, 0, size); /* FIXME: really port to fmap */
106 95
 	if(!buf) {
107 96
 		cli_errmsg("cli_pdf: mmap() failed\n");
... ...
@@ -123,7 +112,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
123 123
 	}
124 124
 
125 125
 	if(!bytesleft) {
126
-	    fmunmap(map);
127 126
 	    cli_dbgmsg("cli_pdf: file header not found\n");
128 127
 	    return CL_CLEAN;
129 128
 	}
... ...
@@ -134,7 +122,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
134 134
 			break;
135 135
 
136 136
 	if(q <= p) {
137
-		fmunmap(map);
138 137
 		cli_dbgmsg("cli_pdf: trailer not found\n");
139 138
 		return CL_CLEAN;
140 139
 	}
... ...
@@ -153,7 +140,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
153 153
 		 * http://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
154 154
 		 * http://www.adobe.com/devnet/pdf/
155 155
 		 */
156
-		fmunmap(map);
157 156
 		cli_dbgmsg("cli_pdf: Encrypted PDF files not yet supported\n");
158 157
 		return CL_CLEAN;
159 158
 	}
... ...
@@ -176,7 +162,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
176 176
 				break;
177 177
 
178 178
 	if(xrefstart == p) {
179
-		fmunmap(map);
180 179
 		cli_dbgmsg("cli_pdf: xref not found\n");
181 180
 		return CL_CLEAN;
182 181
 	}
... ...
@@ -555,7 +540,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
555 555
 		if(rc != CL_CLEAN) break;
556 556
 	}
557 557
 
558
-	fmunmap(map);
559 558
 
560 559
 	tableDestroy(md5table);
561 560
 
... ...
@@ -22,6 +22,6 @@
22 22
 
23 23
 #include "others.h"
24 24
 
25
-int cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset);
25
+int cli_pdf(const char *dir, cli_ctx *ctx, off_t offset);
26 26
 
27 27
 #endif
... ...
@@ -1205,7 +1205,7 @@ static int cli_scantar(int desc, cli_ctx *ctx, unsigned int posix)
1205 1205
     return ret;
1206 1206
 }
1207 1207
 
1208
-static int cli_scanbinhex(int desc, cli_ctx *ctx)
1208
+static int cli_scanbinhex(cli_ctx *ctx)
1209 1209
 {
1210 1210
 	char *dir;
1211 1211
 	int ret = CL_CLEAN;
... ...
@@ -1223,7 +1223,7 @@ static int cli_scanbinhex(int desc, cli_ctx *ctx)
1223 1223
 	return CL_ETMPDIR;
1224 1224
     }
1225 1225
 
1226
-    if((ret = cli_binhex(dir, desc)))
1226
+    if((ret = cli_binhex(dir, *ctx->fmap)))
1227 1227
 	cli_dbgmsg("Binhex: %s\n", cl_strerror(ret));
1228 1228
     else
1229 1229
 	ret = cli_scandir(dir, ctx);
... ...
@@ -1434,7 +1434,7 @@ static int cli_scancryptff(int desc, cli_ctx *ctx)
1434 1434
     return ret;
1435 1435
 }
1436 1436
 
1437
-static int cli_scanpdf(int desc, cli_ctx *ctx, off_t offset)
1437
+static int cli_scanpdf(cli_ctx *ctx, off_t offset)
1438 1438
 {
1439 1439
 	int ret;
1440 1440
 	char *dir = cli_gentemp(ctx->engine->tmpdir);
... ...
@@ -1448,7 +1448,7 @@ static int cli_scanpdf(int desc, cli_ctx *ctx, off_t offset)
1448 1448
 	return CL_ETMPDIR;
1449 1449
     }
1450 1450
 
1451
-    ret = cli_pdf(dir, desc, ctx, offset);
1451
+    ret = cli_pdf(dir, ctx, offset);
1452 1452
 
1453 1453
     if(!ctx->engine->keeptmp)
1454 1454
 	cli_rmdirs(dir);
... ...
@@ -1683,14 +1683,14 @@ static int cli_scanembpe(int desc, cli_ctx *ctx)
1683 1683
     return CL_CLEAN;
1684 1684
 }
1685 1685
 
1686
-static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_t *dettype)
1686
+static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_t *dettype)
1687 1687
 {
1688 1688
 	int ret = CL_CLEAN, nret = CL_CLEAN;
1689 1689
 	struct cli_matched_type *ftoffset = NULL, *fpt;
1690 1690
 	uint32_t lastzip, lastrar;
1691 1691
 	struct cli_exe_info peinfo;
1692 1692
 	unsigned int acmode = AC_SCAN_VIR, break_loop = 0;
1693
-	struct stat sb;
1693
+	struct F_MAP *map = *ctx->fmap;
1694 1694
 
1695 1695
 
1696 1696
     if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel)
... ...
@@ -1699,12 +1699,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg,
1699 1699
     if(typercg)
1700 1700
 	acmode |= AC_SCAN_FT;
1701 1701
 
1702
-    if(lseek(desc, 0, SEEK_SET) < 0) {
1703
-	cli_errmsg("cli_scanraw: lseek() failed\n");
1704
-	return CL_ESEEK;
1705
-    }
1706
-
1707
-    ret = cli_scandesc(desc, ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode);
1702
+    ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode);
1708 1703
 
1709 1704
     if(ret >= CL_TYPENO) {
1710 1705
 	ctx->recursion++;
... ...
@@ -1728,73 +1723,72 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg,
1728 1728
 			    cli_dbgmsg("RAR/RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
1729 1729
 			if(type != CL_TYPE_RAR && have_rar && SCAN_ARCHIVE && fpt->offset < 102400 && (DCONF_ARCH & ARCH_CONF_RAR)) {
1730 1730
 			    cli_dbgmsg("RAR/RAR-SFX signature found at %u\n", (unsigned int) fpt->offset);
1731
-			    nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar);
1731
+			    nret = cli_scanrar(map->fd, ctx, fpt->offset, &lastrar);
1732 1732
 			}
1733 1733
 			break;
1734 1734
 
1735 1735
 		    case CL_TYPE_ZIPSFX:
1736 1736
 			if(type != CL_TYPE_ZIP && SCAN_ARCHIVE && fpt->offset < 102400 && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1737 1737
 			    cli_dbgmsg("ZIP/ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset);
1738
-			    nret = cli_unzip_single(desc, ctx, fpt->offset);
1738
+			    nret = cli_unzip_single(ctx, fpt->offset);
1739 1739
 			}
1740 1740
 			break;
1741 1741
 
1742 1742
 		    case CL_TYPE_CABSFX:
1743 1743
 			if(type != CL_TYPE_MSCAB && SCAN_ARCHIVE && fpt->offset < 102400 && (DCONF_ARCH & ARCH_CONF_CAB)) {
1744 1744
 			    cli_dbgmsg("CAB/CAB-SFX signature found at %u\n", (unsigned int) fpt->offset);
1745
-			    nret = cli_scanmscab(desc, ctx, fpt->offset);
1745
+			    nret = cli_scanmscab(map->fd, ctx, fpt->offset);
1746 1746
 			}
1747 1747
 			break;
1748 1748
 		    case CL_TYPE_ARJSFX:
1749 1749
 			if(type != CL_TYPE_ARJ && SCAN_ARCHIVE && fpt->offset < 102400 && (DCONF_ARCH & ARCH_CONF_ARJ)) {
1750 1750
 			    cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int) fpt->offset);
1751
-			    nret = cli_scanarj(desc, ctx, fpt->offset, &lastrar);
1751
+			    nret = cli_scanarj(map->fd, ctx, fpt->offset, &lastrar);
1752 1752
 			}
1753 1753
 			break;
1754 1754
 
1755 1755
 		    case CL_TYPE_NULSFT:
1756 1756
 		        if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_NSIS) && fpt->offset > 4) {
1757 1757
 			    cli_dbgmsg("NSIS signature found at %u\n", (unsigned int) fpt->offset-4);
1758
-			    nret = cli_scannulsft(desc, ctx, fpt->offset - 4);
1758
+			    nret = cli_scannulsft(map->fd, ctx, fpt->offset - 4);
1759 1759
 			}
1760 1760
 			break;
1761 1761
 
1762 1762
 		    case CL_TYPE_AUTOIT:
1763 1763
 		        if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) {
1764 1764
 			    cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset);
1765
-			    nret = cli_scanautoit(desc, ctx, fpt->offset + 23);
1765
+			    nret = cli_scanautoit(map->fd, ctx, fpt->offset + 23);
1766 1766
 			}
1767 1767
 			break;
1768 1768
 
1769 1769
 		    case CL_TYPE_ISHIELD_MSI:
1770 1770
 		        if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ISHIELD)) {
1771 1771
 			    cli_dbgmsg("ISHIELD-MSI signature found at %u\n", (unsigned int) fpt->offset);
1772
-			    nret = cli_scanishield_msi(desc, ctx, fpt->offset + 14);
1772
+			    nret = cli_scanishield_msi(map->fd, ctx, fpt->offset + 14);
1773 1773
 			}
1774 1774
 			break;
1775 1775
 
1776 1776
 		    case CL_TYPE_PDF:
1777 1777
 			if(type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) {
1778 1778
 			    cli_dbgmsg("PDF signature found at %u\n", (unsigned int) fpt->offset);
1779
-			    nret = cli_scanpdf(desc, ctx, fpt->offset);
1779
+			    nret = cli_scanpdf(ctx, fpt->offset);
1780 1780
 			}
1781 1781
 			break;
1782 1782
 
1783 1783
 		    case CL_TYPE_MSEXE:
1784 1784
  			if(SCAN_PE && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP || type == CL_TYPE_MSOLE2) && ctx->dconf->pe) {
1785
-			    fstat(desc, &sb);
1786
-			    if(sb.st_size > 10485760)
1785
+			    if(map->len > 10485760)
1787 1786
 				break;
1788 1787
 			    memset(&peinfo, 0, sizeof(struct cli_exe_info));
1789 1788
 			    peinfo.offset = fpt->offset;
1790
-			    lseek(desc, fpt->offset, SEEK_SET);
1791
-			    if(cli_peheader(desc, &peinfo) == 0) {
1789
+			    lseek(map->fd, fpt->offset, SEEK_SET);
1790
+			    if(cli_peheader(map->fd, &peinfo) == 0) {
1792 1791
 				cli_dbgmsg("*** Detected embedded PE file at %u ***\n", (unsigned int) fpt->offset);
1793 1792
 				if(peinfo.section)
1794 1793
 				    free(peinfo.section);
1795 1794
 
1796
-				lseek(desc, fpt->offset, SEEK_SET);
1797
-				nret = cli_scanembpe(desc, ctx);
1795
+				lseek(map->fd, fpt->offset, SEEK_SET);
1796
+				nret = cli_scanembpe(map->fd, ctx);
1798 1797
 				break_loop = 1; /* we can stop here and other
1799 1798
 						 * embedded executables will
1800 1799
 						 * be found recursively
... ...
@@ -1819,13 +1813,13 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg,
1819 1819
 	    case CL_TYPE_HTML:
1820 1820
 		if(SCAN_HTML && type == CL_TYPE_TEXT_ASCII && (DCONF_DOC & DOC_CONF_HTML)) {
1821 1821
 		    *dettype = CL_TYPE_HTML;
1822
-		    nret = cli_scanhtml(desc, ctx);
1822
+		    nret = cli_scanhtml(map->fd, ctx);
1823 1823
 		}
1824 1824
 		break;
1825 1825
 
1826 1826
 	    case CL_TYPE_MAIL:
1827 1827
 		if(SCAN_MAIL && type == CL_TYPE_TEXT_ASCII && (DCONF_MAIL & MAIL_CONF_MBOX))
1828
-		    nret = cli_scanmail(desc, ctx);
1828
+		    nret = cli_scanmail(map->fd, ctx);
1829 1829
 		break;
1830 1830
 
1831 1831
 	    default:
... ...
@@ -1842,7 +1836,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg,
1842 1842
     }
1843 1843
 
1844 1844
     if(ret == CL_VIRUS)
1845
-	cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
1845
+	cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, map->fd);
1846 1846
 
1847 1847
     return ret;
1848 1848
 }
... ...
@@ -1912,7 +1906,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
1912 1912
     lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
1913 1913
 
1914 1914
     if(type != CL_TYPE_IGNORED && ctx->engine->sdb) {
1915
-	if((ret = cli_scanraw(desc, ctx, type, 0, &dettype)) == CL_VIRUS) {
1915
+	if((ret = cli_scanraw(ctx, type, 0, &dettype)) == CL_VIRUS) {
1916 1916
 	    fmunmap(*ctx->fmap);
1917 1917
 	    ctx->fmap--; 
1918 1918
 	    return CL_VIRUS;
... ...
@@ -2052,7 +2046,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2052 2052
 
2053 2053
 	case CL_TYPE_BINHEX:
2054 2054
 	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BINHEX))
2055
-		ret = cli_scanbinhex(desc, ctx);
2055
+		ret = cli_scanbinhex(ctx);
2056 2056
 	    break;
2057 2057
 
2058 2058
 	case CL_TYPE_SCRENC:
... ...
@@ -2072,7 +2066,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2072 2072
 
2073 2073
         case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */
2074 2074
 	    if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF))
2075
-		ret = cli_scanpdf(desc, ctx, 0);
2075
+		ret = cli_scanpdf(ctx, 0);
2076 2076
 	    break;
2077 2077
 
2078 2078
 	case CL_TYPE_CRYPTFF:
... ...
@@ -2134,7 +2128,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2134 2134
 
2135 2135
     /* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */
2136 2136
     if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && !ctx->engine->sdb) {
2137
-	if(cli_scanraw(desc, ctx, type, typercg, &dettype) == CL_VIRUS) {
2137
+	if(cli_scanraw(ctx, type, typercg, &dettype) == CL_VIRUS) {
2138 2138
 	    fmunmap(*ctx->fmap);
2139 2139
 	    ctx->fmap--; 
2140 2140
 	    return CL_VIRUS;
... ...
@@ -552,20 +552,15 @@ int cli_unzip(cli_ctx *ctx) {
552 552
   return ret;
553 553
 }
554 554
 
555
-int cli_unzip_single(int f, cli_ctx *ctx, off_t lhoffl) {
555
+int cli_unzip_single(cli_ctx *ctx, off_t lhoffl) {
556 556
   int ret=CL_CLEAN;
557 557
   unsigned int fu=0;
558
-  struct stat st;
559 558
   uint32_t fsize;
560
-  struct F_MAP *map;
559
+  struct F_MAP *map = *ctx->fmap;
561 560
 
562 561
   cli_dbgmsg("in cli_unzip_single\n");
563
-  if (fstat(f, &st)==-1) {
564
-    cli_warnmsg("cli_unzip: fstat() failed\n");
565
-    return CL_ESTAT;
566
-  }
567
-  fsize = (uint32_t)(st.st_size - lhoffl);
568
-  if (lhoffl<0 || lhoffl>st.st_size || (sizeof(off_t)!=sizeof(uint32_t) && (off_t)fsize!=st.st_size - lhoffl)) {
562
+  fsize = (uint32_t)(map->len - lhoffl);
563
+  if (lhoffl<0 || lhoffl>map->len || (sizeof(off_t)!=sizeof(uint32_t) && (off_t)fsize!=map->len - lhoffl)) {
569 564
     cli_dbgmsg("cli_unzip: bad offset\n");
570 565
     return CL_CLEAN;
571 566
   }
... ...
@@ -574,13 +569,7 @@ int cli_unzip_single(int f, cli_ctx *ctx, off_t lhoffl) {
574 574
     return CL_CLEAN;
575 575
   }
576 576
 
577
-  if (!(map = fmap(f, 0, st.st_size))) {
578
-      cli_dbgmsg("cli_unzip: mmap failed\n");
579
-      return CL_EMAP;
580
-  }
581
-
582 577
   lhdr(map, lhoffl, fsize, &fu, 0, NULL, &ret, ctx, NULL);
583 578
 
584
-  fmunmap(map);
585 579
   return ret;
586 580
 }
... ...
@@ -27,7 +27,7 @@
27 27
 
28 28
 #include "others.h"
29 29
 int cli_unzip(cli_ctx *);
30
-int cli_unzip_single(int, cli_ctx *, off_t);
30
+int cli_unzip_single(cli_ctx *, off_t);
31 31
 
32 32
 #ifdef UNZIP_PRIVATE
33 33
 #define F_ENCR  (1<<0)