git-svn: trunk@4529
aCaB authored on 2008/12/05 01:27:04... | ... |
@@ -77,14 +77,16 @@ am__clamav_milter_SOURCES_DIST = $(top_srcdir)/shared/cfgparser.c \ |
77 | 77 |
$(top_srcdir)/shared/output.h $(top_srcdir)/shared/getopt.c \ |
78 | 78 |
$(top_srcdir)/shared/getopt.h $(top_srcdir)/shared/misc.c \ |
79 | 79 |
$(top_srcdir)/shared/misc.h $(top_srcdir)/shared/options.c \ |
80 |
- $(top_srcdir)/shared/options.h connpool.c connpool.h netcode.c \ |
|
81 |
- netcode.h clamfi.c clamfi.h clamav-milter.c |
|
80 |
+ $(top_srcdir)/shared/options.h whitelist.c whitelist.h \ |
|
81 |
+ connpool.c connpool.h netcode.c netcode.h clamfi.c clamfi.h \ |
|
82 |
+ clamav-milter.c |
|
82 | 83 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@am_clamav_milter_OBJECTS = \ |
83 | 84 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ cfgparser.$(OBJEXT) \ |
84 | 85 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ output.$(OBJEXT) \ |
85 | 86 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ getopt.$(OBJEXT) \ |
86 | 87 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ misc.$(OBJEXT) \ |
87 | 88 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ options.$(OBJEXT) \ |
89 |
+@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ whitelist.$(OBJEXT) \ |
|
88 | 90 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ connpool.$(OBJEXT) \ |
89 | 91 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ netcode.$(OBJEXT) \ |
90 | 92 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ clamfi.$(OBJEXT) \ |
... | ... |
@@ -279,6 +281,8 @@ top_srcdir = @top_srcdir@ |
279 | 279 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ $(top_srcdir)/shared/misc.h \ |
280 | 280 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ $(top_srcdir)/shared/options.c \ |
281 | 281 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ $(top_srcdir)/shared/options.h \ |
282 |
+@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ whitelist.c \ |
|
283 |
+@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ whitelist.h \ |
|
282 | 284 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ connpool.c \ |
283 | 285 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ connpool.h \ |
284 | 286 |
@BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@ netcode.c \ |
... | ... |
@@ -387,6 +391,7 @@ distclean-compile: |
387 | 387 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netcode.Po@am__quote@ |
388 | 388 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ |
389 | 389 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@ |
390 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whitelist.Po@am__quote@ |
|
390 | 391 |
|
391 | 392 |
.c.o: |
392 | 393 |
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
... | ... |
@@ -42,7 +42,7 @@ |
42 | 42 |
#include "connpool.h" |
43 | 43 |
#include "netcode.h" |
44 | 44 |
#include "clamfi.h" |
45 |
- |
|
45 |
+#include "whitelist.h" |
|
46 | 46 |
|
47 | 47 |
struct smfiDesc descr = { |
48 | 48 |
"ClamAV", /* filter name */ |
... | ... |
@@ -214,6 +214,12 @@ int main(int argc, char **argv) { |
214 | 214 |
return 1; |
215 | 215 |
} |
216 | 216 |
|
217 |
+ if((cpt = cfgopt(copt, "Whitelist"))->enabled && whitelist_init(cpt->strarg)) { |
|
218 |
+ localnets_free(); |
|
219 |
+ logg_close(); |
|
220 |
+ freecfg(copt); |
|
221 |
+ return 1; |
|
222 |
+ } |
|
217 | 223 |
|
218 | 224 |
/* FIXME: find a place for these: |
219 | 225 |
* maxthreads = cfgopt(copt, "MaxThreads")->numarg; |
... | ... |
@@ -239,18 +245,24 @@ int main(int argc, char **argv) { |
239 | 239 |
umask(0007); |
240 | 240 |
if(!(my_socket = cfgopt(copt, "MilterSocket")->strarg)) { |
241 | 241 |
logg("!Please configure the MilterSocket directive\n"); |
242 |
+ localnets_free(); |
|
243 |
+ whitelist_free(); |
|
242 | 244 |
logg_close(); |
243 | 245 |
freecfg(copt); |
244 | 246 |
return 1; |
245 | 247 |
} |
246 | 248 |
if(smfi_setconn(my_socket) == MI_FAILURE) { |
247 | 249 |
logg("!smfi_setconn failed\n"); |
250 |
+ localnets_free(); |
|
251 |
+ whitelist_free(); |
|
248 | 252 |
logg_close(); |
249 | 253 |
freecfg(copt); |
250 | 254 |
return 1; |
251 | 255 |
} |
252 | 256 |
if(smfi_register(descr) == MI_FAILURE) { |
253 | 257 |
logg("!smfi_register failed\n"); |
258 |
+ localnets_free(); |
|
259 |
+ whitelist_free(); |
|
254 | 260 |
logg_close(); |
255 | 261 |
freecfg(copt); |
256 | 262 |
return 1; |
... | ... |
@@ -258,6 +270,8 @@ int main(int argc, char **argv) { |
258 | 258 |
cpt = cfgopt(copt, "FixStaleSocket"); |
259 | 259 |
if(smfi_opensocket(cpt->enabled) == MI_FAILURE) { |
260 | 260 |
logg("!Failed to create socket %s\n", my_socket); |
261 |
+ localnets_free(); |
|
262 |
+ whitelist_free(); |
|
261 | 263 |
logg_close(); |
262 | 264 |
freecfg(copt); |
263 | 265 |
return 1; |
... | ... |
@@ -269,6 +283,8 @@ int main(int argc, char **argv) { |
269 | 269 |
cpool_init(copt); |
270 | 270 |
if (!cp) { |
271 | 271 |
logg("!Failed to init the socket pool\n"); |
272 |
+ localnets_free(); |
|
273 |
+ whitelist_free(); |
|
272 | 274 |
logg_close(); |
273 | 275 |
freecfg(copt); |
274 | 276 |
return 1; |
... | ... |
@@ -277,6 +293,8 @@ int main(int argc, char **argv) { |
277 | 277 |
if(!cfgopt(copt, "Foreground")->enabled) { |
278 | 278 |
if(daemonize() == -1) { |
279 | 279 |
logg("!daemonize() failed\n"); |
280 |
+ localnets_free(); |
|
281 |
+ whitelist_free(); |
|
280 | 282 |
cpool_free(); |
281 | 283 |
logg_close(); |
282 | 284 |
return 1; |
... | ... |
@@ -293,8 +311,11 @@ int main(int argc, char **argv) { |
293 | 293 |
logg_close(); |
294 | 294 |
cpool_free(); |
295 | 295 |
localnets_free(); |
296 |
+ whitelist_free(); |
|
297 |
+ |
|
296 | 298 |
return ret; |
297 | 299 |
} |
300 |
+ |
|
298 | 301 |
/* |
299 | 302 |
* Local Variables: |
300 | 303 |
* mode: c |
301 | 304 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,124 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C)2008 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Author: aCaB <acab@clamav.net> |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#if HAVE_CONFIG_H |
|
21 |
+#include "clamav-config.h" |
|
22 |
+#endif |
|
23 |
+ |
|
24 |
+#include <stdio.h> |
|
25 |
+#include <string.h> |
|
26 |
+#include <sys/types.h> |
|
27 |
+#include <regex.h> |
|
28 |
+ |
|
29 |
+#include "shared/output.h" |
|
30 |
+ |
|
31 |
+struct WHLST { |
|
32 |
+ regex_t preg; |
|
33 |
+ struct WHLST *next; |
|
34 |
+}; |
|
35 |
+ |
|
36 |
+struct WHLST *wfrom = NULL; |
|
37 |
+struct WHLST *wto = NULL; |
|
38 |
+ |
|
39 |
+void whitelist_free(void) { |
|
40 |
+ struct WHLST *w; |
|
41 |
+ while(wfrom) { |
|
42 |
+ w = wfrom->next; |
|
43 |
+ regfree(&wfrom->preg); |
|
44 |
+ free(wfrom); |
|
45 |
+ wfrom = w; |
|
46 |
+ } |
|
47 |
+ while(wto) { |
|
48 |
+ w = wfrom->next; |
|
49 |
+ regfree(&wto->preg); |
|
50 |
+ free(wto); |
|
51 |
+ wto = w; |
|
52 |
+ } |
|
53 |
+} |
|
54 |
+ |
|
55 |
+int whitelist_init(const char *fname) { |
|
56 |
+ char buf[2048]; |
|
57 |
+ FILE *f; |
|
58 |
+ struct WHLST *w; |
|
59 |
+ |
|
60 |
+ if(!(f = fopen(fname, "r"))) { |
|
61 |
+ logg("!Cannot open whitelist file\n"); |
|
62 |
+ return 1; |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ while(fgets(buf, sizeof(buf), f) != NULL) { |
|
66 |
+ struct WHLST **addto = &wto; |
|
67 |
+ char *ptr = buf; |
|
68 |
+ int len; |
|
69 |
+ |
|
70 |
+ if(*buf == '#' || *buf == ':' || *buf == '!') |
|
71 |
+ continue; |
|
72 |
+ |
|
73 |
+ if(!strncasecmp("From:", buf, 5)) { |
|
74 |
+ ptr+=5; |
|
75 |
+ addto = &wfrom; |
|
76 |
+ } else if (!strncasecmp("To:", buf, 3)) |
|
77 |
+ ptr+=3; |
|
78 |
+ |
|
79 |
+ len = strlen(ptr) - 1; |
|
80 |
+ for(;len>=0; len--) { |
|
81 |
+ if(buf[len] != '\n' && buf[len] != '\r') break; |
|
82 |
+ buf[len] = '\0'; |
|
83 |
+ } |
|
84 |
+ if(!len) continue; |
|
85 |
+ if (!(w = (struct WHLST *)malloc(sizeof(*w)))) { |
|
86 |
+ logg("!Out of memory loading whitelist\n"); |
|
87 |
+ whitelist_free(); |
|
88 |
+ return 1; |
|
89 |
+ } |
|
90 |
+ w->next = (*addto)->next; |
|
91 |
+ (*addto) = w; |
|
92 |
+ if (regcomp(&w->preg, ptr, REG_ICASE|REG_NOSUB)) { |
|
93 |
+ logg("!Failed to compile regex '%s'\n", ptr); |
|
94 |
+ whitelist_free(); |
|
95 |
+ return 1; |
|
96 |
+ } |
|
97 |
+ } |
|
98 |
+ return 0; |
|
99 |
+} |
|
100 |
+ |
|
101 |
+ |
|
102 |
+int whitelisted(const char *e, int from) { |
|
103 |
+ struct WHLST *w; |
|
104 |
+ |
|
105 |
+ if(from) w = wfrom; |
|
106 |
+ else w = wto; |
|
107 |
+ while(w) { |
|
108 |
+ if(!regexec(&w->preg, e, 0, NULL, 0)) |
|
109 |
+ return 1; |
|
110 |
+ w = w->next; |
|
111 |
+ } |
|
112 |
+ return 0; |
|
113 |
+} |
|
114 |
+ |
|
115 |
+ |
|
116 |
+/* |
|
117 |
+ * Local Variables: |
|
118 |
+ * mode: c |
|
119 |
+ * c-basic-offset: 4 |
|
120 |
+ * tab-width: 8 |
|
121 |
+ * End: |
|
122 |
+ * vim: set cindent smartindent autoindent softtabstop=4 shiftwidth=4 tabstop=8: |
|
123 |
+ */ |
... | ... |
@@ -16,39 +16,48 @@ Example |
16 | 16 |
# [[unix|local]:]/path/to/file - to specify a unix domain socket |
17 | 17 |
# inet:port@[hostname|ip-address] - to specify an ipv4 socket |
18 | 18 |
# inet6:port@[hostname|ip-address] - to specify an ipv6 socket |
19 |
-#Default: no default |
|
19 |
+# |
|
20 |
+# Default: no default |
|
20 | 21 |
##MilterSocket /tmp/clamav-milter.socket |
21 | 22 |
##MilterSocket inet:7357 |
22 | 23 |
|
23 | 24 |
# Remove stale socket after unclean shutdown. |
25 |
+# |
|
24 | 26 |
# Default: yes |
25 | 27 |
##FixStaleSocket yes |
26 | 28 |
|
27 | 29 |
# Maximum number of threads running at the same time. |
30 |
+# |
|
28 | 31 |
# Default: 10 |
29 | 32 |
##MaxThreads 20 |
30 | 33 |
|
31 | 34 |
# Run as another user (clamav-milter must be started by root for this option to work) |
32 |
-# Default: don't drop privileges |
|
35 |
+# |
|
36 |
+# Default: unset (don't drop privileges) |
|
33 | 37 |
##User clamav |
34 | 38 |
|
35 | 39 |
# Initialize supplementary group access (clamd must be started by root). |
40 |
+# |
|
36 | 41 |
# Default: no |
37 | 42 |
##AllowSupplementaryGroups no |
38 | 43 |
|
39 | 44 |
# Waiting for data from clamd will timeout after this time (seconds). |
40 | 45 |
# Value of 0 disables the timeout. |
46 |
+# |
|
41 | 47 |
# Default: 120 |
42 | 48 |
##ReadTimeout 300 |
43 | 49 |
|
44 | 50 |
# Don't fork into background. |
51 |
+# |
|
45 | 52 |
# Default: no |
46 | 53 |
##Foreground yes |
47 | 54 |
|
48 | 55 |
# Chroot to the specified directory. |
49 | 56 |
# Chrooting is performed just after reading the config file and before dropping privileges. |
57 |
+# |
|
50 | 58 |
# Default: unset (don't chroot) |
51 |
-#Chroot /newroot |
|
59 |
+##Chroot /newroot |
|
60 |
+ |
|
52 | 61 |
|
53 | 62 |
## |
54 | 63 |
## Clamd options |
... | ... |
@@ -88,11 +97,23 @@ Example |
88 | 88 |
# This option takes a host(name)/mask pair in CIRD notation and can be |
89 | 89 |
# repeated several times. If "/mask" is omitted, a host is assumed. |
90 | 90 |
# To specify a locally orignated, non-smtp, email use the keyword "local" |
91 |
+# |
|
91 | 92 |
# Default: unset (scan everything regardless of the origin) |
92 | 93 |
#LocalNet local |
93 | 94 |
#LocalNet 192.168.0.0/24 |
94 | 95 |
#LocalNet 1111:2222:3333::/48 |
95 | 96 |
|
97 |
+# This option specifies a file which contains a list of e-mail addresses. |
|
98 |
+# E-mails sent to or from these addresses will NOT be checked. |
|
99 |
+# The file consists of a list of addresses, each address on a line enclosed |
|
100 |
+# in angle brackets (e.g. <foo@bar.com>). |
|
101 |
+# Optionally each line can start with the string "To:" or "From:" indicating |
|
102 |
+# if it is the sender or recipient that is to be whitelisted. If the field |
|
103 |
+# is missing, the default is "To:". Lines starting with #, : or ! are ignored. |
|
104 |
+# |
|
105 |
+# Default unset (no exclusion applied) |
|
106 |
+#Whitelist /etc/whitelisted_addresses |
|
107 |
+ |
|
96 | 108 |
|
97 | 109 |
## |
98 | 110 |
## Actions |
... | ... |
@@ -142,12 +163,14 @@ Example |
142 | 142 |
# Uncomment this option to enable logging. |
143 | 143 |
# LogFile must be writable for the user running daemon. |
144 | 144 |
# A full path is required. |
145 |
+# |
|
145 | 146 |
# Default: disabled |
146 | 147 |
##LogFile /tmp/clamav-milter.log |
147 | 148 |
|
148 | 149 |
# By default the log file is locked for writing - the lock protects against |
149 | 150 |
# running clamav-milter multiple times. |
150 | 151 |
# This option disables log file locking. |
152 |
+# |
|
151 | 153 |
# Default: no |
152 | 154 |
##LogFileUnlock yes |
153 | 155 |
|
... | ... |
@@ -156,28 +179,34 @@ Example |
156 | 156 |
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes) |
157 | 157 |
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size |
158 | 158 |
# in bytes just don't use modifiers. |
159 |
+# |
|
159 | 160 |
# Default: 1M |
160 | 161 |
##LogFileMaxSize 2M |
161 | 162 |
|
162 | 163 |
# Log time with each message. |
164 |
+# |
|
163 | 165 |
# Default: no |
164 | 166 |
##LogTime yes |
165 | 167 |
|
166 | 168 |
# Also log clean files. Useful in debugging but drastically increases the |
167 | 169 |
# log size. |
170 |
+# |
|
168 | 171 |
# Default: no |
169 | 172 |
##LogClean yes |
170 | 173 |
|
171 | 174 |
# Use system logger (can work together with LogFile). |
175 |
+# |
|
172 | 176 |
# Default: no |
173 | 177 |
##LogSyslog yes |
174 | 178 |
|
175 | 179 |
# Specify the type of syslog messages - please refer to 'man syslog' |
176 | 180 |
# for facility names. |
181 |
+# |
|
177 | 182 |
# Default: LOG_LOCAL6 |
178 | 183 |
##LogFacility LOG_MAIL |
179 | 184 |
|
180 | 185 |
# Enable verbose logging. |
186 |
+# |
|
181 | 187 |
# Default: no |
182 | 188 |
##LogVerbose yes |
183 | 189 |
|
... | ... |
@@ -225,7 +254,7 @@ Example |
225 | 225 |
|
226 | 226 |
|
227 | 227 |
#Todo |
228 |
-#-C --chroot |
|
228 |
+##-C --chroot |
|
229 | 229 |
#-D --debug |
230 | 230 |
#-i --pidfile |
231 | 231 |
##-I --ignore |