1 /*
2  *  Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3  *  Copyright (C) 2007-2013 Sourcefire, Inc.
4  *
5  *  Authors: Alberto Wu
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  */
21 
22 #ifndef __UNZIP_H
23 #define __UNZIP_H
24 
25 #if HAVE_CONFIG_H
26 #include "clamav-config.h"
27 #endif
28 
29 #include "others.h"
30 
31 typedef cl_error_t (*zip_cb)(int fd, const char *filepath, cli_ctx *ctx, const char *name);
32 #define zip_scan_cb cli_magic_scan_desc
33 
34 #define MAX_ZIP_REQUESTS 10
35 struct zip_requests {
36     const char *names[MAX_ZIP_REQUESTS];
37     size_t namelens[MAX_ZIP_REQUESTS];
38     int namecnt;
39 
40     uint32_t loff;
41     int found, match;
42 };
43 
44 cl_error_t cli_unzip(cli_ctx *);
45 cl_error_t unzip_single_internal(cli_ctx *, off_t, zip_cb);
46 cl_error_t cli_unzip_single(cli_ctx *, off_t);
47 
48 cl_error_t unzip_search_add(struct zip_requests *, const char *, size_t);
49 cl_error_t unzip_search(cli_ctx *, fmap_t *, struct zip_requests *);
50 cl_error_t unzip_search_single(cli_ctx *, const char *, size_t, uint32_t *);
51 
52 // clang-format off
53 #ifdef UNZIP_PRIVATE
54 #define F_ENCR  (1<<0)
55 #define F_ALGO1 (1<<1)
56 #define F_ALGO2 (1<<2)
57 #define F_USEDD (1<<3)
58 #define F_RSVD1 (1<<4)
59 #define F_PATCH (1<<5)
60 #define F_STRNG (1<<6)
61 #define F_UNUS1 (1<<7)
62 #define F_UNUS2 (1<<8)
63 #define F_UNUS3 (1<<9)
64 #define F_UNUS4 (1<<10)
65 #define F_UTF8  (1<<11)
66 #define F_RSVD2 (1<<12)
67 #define F_MSKED (1<<13)
68 #define F_RSVD3 (1<<14)
69 #define F_RSVD4 (1<<15)
70 // clang-format on
71 
72 enum ALGO {
73     ALG_STORED,
74     ALG_SHRUNK,
75     ALG_REDUCE1,
76     ALG_REDUCE2,
77     ALG_REDUCE3,
78     ALG_REDUCE4,
79     ALG_IMPLODE,
80     ALG_TOKENZD,
81     ALG_DEFLATE,
82     ALG_DEFLATE64,
83     ALG_OLDTERSE,
84     ALG_RSVD1,
85     ALG_BZIP2,
86     ALG_RSVD2,
87     ALG_LZMA,
88     ALG_RSVD3,
89     ALG_RSVD4,
90     ALG_RSVD5,
91     ALG_NEWTERSE,
92     ALG_LZ77,
93     ALG_WAVPACK = 97,
94     ALG_PPMD
95 };
96 
97 /*
98  * Local File Header format:
99  */
100 /* struct LH { */
101 /*   uint32_t magic; */
102 /*   uint16_t version; */
103 /*   uint16_t flags; */
104 /*   uint16_t method; */
105 /*   uint32_t mtime; */
106 /*   uint32_t crc32; */
107 /*   uint32_t csize; */
108 /*   uint32_t usize; */
109 /*   uint16_t flen; */
110 /*   uint16_t elen; */
111 /*   char fname[flen] */
112 /*   char extra[elen] */
113 /* } __attribute__((packed)); */
114 
115 /*
116  * Local File Header convenience macros:
117  */
118 // clang-format off
119 #define LOCAL_HEADER_magic   ((uint32_t)cli_readint32((uint8_t *)(local_header)+0))
120 #define LOCAL_HEADER_version ((uint16_t)cli_readint16((uint8_t *)(local_header)+4))
121 #define LOCAL_HEADER_flags   ((uint16_t)cli_readint16((uint8_t *)(local_header)+6))
122 #define LOCAL_HEADER_method  ((uint16_t)cli_readint16((uint8_t *)(local_header)+8))
123 #define LOCAL_HEADER_mtime   ((uint32_t)cli_readint32((uint8_t *)(local_header)+10))
124 #define LOCAL_HEADER_crc32   ((uint32_t)cli_readint32((uint8_t *)(local_header)+14))
125 #define LOCAL_HEADER_csize   ((uint32_t)cli_readint32((uint8_t *)(local_header)+18))
126 #define LOCAL_HEADER_usize   ((uint32_t)cli_readint32((uint8_t *)(local_header)+22))
127 #define LOCAL_HEADER_flen    ((uint16_t)cli_readint16((uint8_t *)(local_header)+26))
128 #define LOCAL_HEADER_elen    ((uint16_t)cli_readint16((uint8_t *)(local_header)+28))
129 #define SIZEOF_LOCAL_HEADER 30
130 // clang-format on
131 
132 /*
133  * Central Directory File Header format:
134  */
135 /* struct CH { */
136 /*   uint32_t magic; */
137 /*   uint16_t vermade; */
138 /*   uint16_t verneed; */
139 /*   uint16_t flags; */
140 /*   uint16_t method; */
141 /*   uint32_t mtime; */
142 /*   uint32_t crc32; */
143 /*   uint32_t csize; */
144 /*   uint32_t usize; */
145 /*   uint16_t flen; */
146 /*   uint16_t elen; */
147 /*   uint16_t clen; */
148 /*   uint16_t dsk; */
149 /*   uint16_t iattrib; */
150 /*   uint32_t eattrib; */
151 /*   uint32_t off; */
152 /*   char fname[flen] */
153 /*   char extra[elen] */
154 /*   char comment[clen] */
155 /* } __attribute__((packed)); */
156 
157 /*
158  * Central Directory File Header convenience macro's:
159  */
160 // clang-format off
161 #define CENTRAL_HEADER_magic        ((uint32_t)cli_readint32((uint8_t *)(central_header)+0))
162 #define CENTRAL_HEADER_vermade      ((uint16_t)cli_readint16((uint8_t *)(central_header)+4))
163 #define CENTRAL_HEADER_verneed      ((uint16_t)cli_readint16((uint8_t *)(central_header)+6))
164 #define CENTRAL_HEADER_flags        ((uint16_t)cli_readint16((uint8_t *)(central_header)+8))
165 #define CENTRAL_HEADER_method       ((uint16_t)cli_readint16((uint8_t *)(central_header)+10))
166 #define CENTRAL_HEADER_mtime        ((uint32_t)cli_readint32((uint8_t *)(central_header)+12))
167 #define CENTRAL_HEADER_crc32        ((uint32_t)cli_readint32((uint8_t *)(central_header)+16))
168 #define CENTRAL_HEADER_csize        ((uint32_t)cli_readint32((uint8_t *)(central_header)+20))
169 #define CENTRAL_HEADER_usize        ((uint32_t)cli_readint32((uint8_t *)(central_header)+24))
170 #define CENTRAL_HEADER_flen         ((uint16_t)cli_readint16((uint8_t *)(central_header)+28))
171 #define CENTRAL_HEADER_extra_len    ((uint16_t)cli_readint16((uint8_t *)(central_header)+30))
172 #define CENTRAL_HEADER_comment_len  ((uint16_t)cli_readint16((uint8_t *)(central_header)+32))
173 #define CENTRAL_HEADER_disk_num     ((uint16_t)cli_readint16((uint8_t *)(central_header)+34))
174 #define CENTRAL_HEADER_iattrib      ((uint16_t)cli_readint16((uint8_t *)(central_header)+36))
175 #define CENTRAL_HEADER_eattrib      ((uint32_t)cli_readint32((uint8_t *)(central_header)+38))
176 #define CENTRAL_HEADER_off          ((uint32_t)cli_readint32((uint8_t *)(central_header)+42))
177 // clang-format on
178 
179 #define SIZEOF_CENTRAL_HEADER 46
180 #define SIZEOF_ENCRYPTION_HEADER 12
181 #endif /* UNZIP_PRIVATE */
182 
183 #endif /* __UNZIP_H */
184