]> git.pld-linux.org Git - packages/vsftpd.git/blame - vsftpd-clamav.patch
- not for AC + some todo's
[packages/vsftpd.git] / vsftpd-clamav.patch
CommitLineData
ba8b947d
MM
1Add support for scanning uploaded files with clamav. Not all features are
2implemented (ex. file inclusion/exclusion for scanning). Every uploaded file is
3saved in random named file, and moved to destination file after scanning. Side
4effects: when uploaded *new* file was infected, 0-size file left.
5
6Written by Marek Marczykowski <m.marczykowski@fiok.pl>
7
48e27130
MM
8diff -Naru vsftpd-2.2.2.orig/Makefile vsftpd-2.2.2/Makefile
9--- vsftpd-2.2.2.orig/Makefile 2009-05-22 21:44:52.000000000 +0200
10+++ vsftpd-2.2.2/Makefile 2010-04-29 19:46:54.435448038 +0200
ba8b947d
MM
11@@ -14,7 +14,7 @@
12 banner.o filestr.o parseconf.o secutil.o \
13 ascii.o oneprocess.o twoprocess.o privops.o standalone.o hash.o \
14 tcpwrap.o ipaddrparse.o access.o features.o readwrite.o opts.o \
15- ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o
16+ ssl.o sslslave.o ptracesandbox.o ftppolicy.o sysutil.o sysdeputil.o clamav.o
17
18
19 .c.o:
48e27130
MM
20diff -Naru vsftpd-2.2.2.orig/clamav.c vsftpd-2.2.2/clamav.c
21--- vsftpd-2.2.2.orig/clamav.c 1970-01-01 01:00:00.000000000 +0100
22+++ vsftpd-2.2.2/clamav.c 2010-04-29 19:46:54.435448038 +0200
ba8b947d
MM
23@@ -0,0 +1,221 @@
24+#include <sys/types.h>
25+#include <regex.h>
26+#include <sys/socket.h>
27+#include <linux/un.h>
28+#include <arpa/inet.h>
29+#include <netdb.h>
30+#include <sys/socket.h>
31+#include <stdio.h>
32+#include "clamav.h"
33+#include "tunables.h"
34+#include "utility.h"
35+#include "sysutil.h"
36+#include "logging.h"
37+#include "sysstr.h"
38+
39+regex_t av_include_files_regex, av_exclude_files_regex;
40+
41+int av_init() {
42+ int ret;
43+
44+ if (tunable_av_enable) {
45+ if (tunable_av_include_files) {
46+ if ((ret=regcomp(&av_include_files_regex, tunable_av_include_files, REG_NOSUB)) != 0)
47+ die("regex compilation failed for AvIncludeFiles");
48+ }
49+ if (tunable_av_exclude_files) {
50+ if ((ret=regcomp(&av_exclude_files_regex, tunable_av_exclude_files, REG_NOSUB)) != 0)
51+ die("regex compilation failed for AvExcludeFiles");
52+ }
53+ }
54+ return 0;
55+}
56+
57+int av_will_scan(const char *filename) {
58+ if (!tunable_av_enable)
59+ return 0;
60+ if (tunable_av_include_files && (regexec(&av_include_files_regex, filename, 0, 0, 0)!=0))
61+ return 0;
62+ if (tunable_av_exclude_files && (regexec(&av_exclude_files_regex, filename, 0, 0, 0)==0))
63+ return 0;
64+ return 1;
65+}
66+
67+int av_init_scanner (struct vsf_session* p_sess) {
68+ struct mystr debug_str = INIT_MYSTR;
69+
70+ if (p_sess->clamd_sock < 0) {
71+
72+ /* connect to clamd through local unix socket */
73+ if (tunable_av_clamd_socket) {
74+ struct sockaddr_un server_local;
75+
76+ vsf_sysutil_memclr((char*)&server_local, sizeof(server_local));
77+
78+ server_local.sun_family = AF_UNIX;
79+ vsf_sysutil_strcpy(server_local.sun_path, tunable_av_clamd_socket, sizeof(server_local.sun_path));
80+ if ((p_sess->clamd_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
81+ str_alloc_text(&debug_str, "av: error opening unix socket");
82+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
83+ p_sess->clamd_sock = -2;
84+ return 0;
85+ }
86+
87+ if (connect(p_sess->clamd_sock, (struct sockaddr *)&server_local, sizeof(struct sockaddr_un)) < 0) {
88+ str_alloc_text(&debug_str, "av: error connecting to clamd");
89+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
90+ p_sess->clamd_sock = -2;
91+ return 0;
92+ }
93+
94+ } else if (tunable_av_clamd_host) {
95+ struct sockaddr_in server_inet;
96+ struct hostent *he;
97+
98+ vsf_sysutil_memclr((char*)&server_inet, sizeof(server_inet));
99+
100+ /* Remote Socket */
101+ server_inet.sin_family = AF_INET;
102+ server_inet.sin_port = htons(tunable_av_clamd_port);
103+
104+ if ((p_sess->clamd_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
105+ str_alloc_text(&debug_str, "av: error opening inet socket");
106+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
107+ p_sess->clamd_sock = -2;
108+ return 0;
109+ }
110+
111+ if ((he = gethostbyname(tunable_av_clamd_host)) == 0) {
112+ str_alloc_text(&debug_str, "av: unable to locate clamd host");
113+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
114+ vsf_sysutil_close_failok(p_sess->clamd_sock);
115+ p_sess->clamd_sock = -2;
116+ return 0;
117+ }
118+
119+ server_inet.sin_addr = *(struct in_addr *) he->h_addr_list[0];
120+
121+ if (connect(p_sess->clamd_sock, (struct sockaddr *)&server_inet, sizeof(struct sockaddr_in)) < 0) {
122+ str_alloc_text(&debug_str, "av: error connecting to clamd host");
123+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
124+ vsf_sysutil_close_failok(p_sess->clamd_sock);
125+ p_sess->clamd_sock = -2;
126+ return 0;
127+ }
128+ }
129+
130+ if (vsf_sysutil_write(p_sess->clamd_sock, "nIDSESSION\n", 11) <= 0) {
131+ str_alloc_text(&debug_str, "av: error starting clamd session");
132+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
133+ vsf_sysutil_close_failok(p_sess->clamd_sock);
134+ p_sess->clamd_sock = -2;
135+ return 0;
136+ }
137+ }
138+
139+ return 1;
140+}
141+
142+int av_scan_file(struct vsf_session* p_sess, struct mystr *filename, struct mystr *virname) {
143+ struct mystr cwd = INIT_MYSTR;
144+ struct mystr clamcmd = INIT_MYSTR;
145+ struct mystr response = INIT_MYSTR;
146+ char recv_buff[4096];
147+ int recv_count;
148+ struct str_locate_result locate_res;
149+ struct mystr debug_str = INIT_MYSTR;
150+ int retry = 0;
151+
152+init_scan:
153+ if (av_init_scanner(p_sess)) {
154+
155+ str_alloc_text(&clamcmd, "nSCAN ");
156+ if (!str_isempty(&p_sess->chroot_str)) {
157+ str_append_str(&clamcmd, &p_sess->chroot_str);
158+ }
159+ if (str_get_char_at(filename, 0) != '/') {
160+ str_getcwd(&cwd);
161+ str_append_str(&clamcmd, &cwd);
162+ }
163+ if (str_get_char_at(&clamcmd, str_getlen(&clamcmd) - 1) != '/') {
164+ str_append_char(&clamcmd, '/');
165+ }
166+ str_append_str(&clamcmd, filename);
167+ str_append_char(&clamcmd, '\n');
168+
169+// sprintf(recv_buff, "sockfd: %d", p_sess->clamd_sock);
170+// str_alloc_text(&debug_str, recv_buff);
171+// vsf_log_line(p_sess, kVSFLogEntryDebug, &p_sess->chroot_str);
172+// vsf_log_line(p_sess, kVSFLogEntryDebug, &clamcmd);
173+
174+ if (vsf_sysutil_write(p_sess->clamd_sock, str_getbuf(&clamcmd), str_getlen(&clamcmd)) <= 0) {
175+ str_alloc_text(&debug_str, "av: failed to scan file");
176+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
177+ vsf_sysutil_close_failok(p_sess->clamd_sock);
178+ p_sess->clamd_sock = -2;
179+ return 2;
180+ }
181+
182+ str_free(&clamcmd);
183+
184+ /* receive and interpret answer */
185+ while ((recv_count=vsf_sysutil_read(p_sess->clamd_sock, recv_buff, 4095)) > 0) {
186+ recv_buff[recv_count]=0;
187+ str_append_text(&response, recv_buff);
188+ if (recv_buff[recv_count-1] == '\n')
189+ break;
190+ }
191+ if (recv_count < 0 || str_getlen(&response) == 0) {
192+ if (!retry) {
193+ retry = 1;
194+ vsf_sysutil_close_failok(p_sess->clamd_sock);
195+ p_sess->clamd_sock = -2;
196+ goto init_scan;
197+ } else {
198+ str_alloc_text(&debug_str, "av: failed to scan file (read failed)");
199+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
200+ vsf_sysutil_close(p_sess->clamd_sock);
201+ p_sess->clamd_sock = -2;
202+ return 2;
203+ }
204+ }
205+
206+ if (str_equal_text(&response, "COMMAND READ TIMED OUT\n")) {
207+ if (!retry) {
208+ retry = 1;
209+ vsf_sysutil_close_failok(p_sess->clamd_sock);
210+ p_sess->clamd_sock = -2;
211+ goto init_scan;
212+ } else {
213+ str_alloc_text(&debug_str, "av: got: ");
214+ str_append_str(&debug_str, &response);
215+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
216+ return 2;
217+ }
218+ }
219+
220+
221+
222+ locate_res = str_locate_text(&response, " FOUND\n");
223+ /* virus found */
224+ if (locate_res.found) {
225+ str_trunc(&response, locate_res.index);
226+ str_split_text_reverse(&response, virname, ": ");
227+ return 1;
228+ }
229+ locate_res = str_locate_text(&response, " ERROR\n");
230+ if (locate_res.found) {
231+ str_alloc_text(&debug_str, "av: got: ");
232+ str_append_str(&debug_str, &response);
233+ vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
234+ return 2;
235+ }
236+ return 0;
237+ }
238+
239+ return 2;
240+}
241+
242+
243+
244+
48e27130
MM
245diff -Naru vsftpd-2.2.2.orig/clamav.h vsftpd-2.2.2/clamav.h
246--- vsftpd-2.2.2.orig/clamav.h 1970-01-01 01:00:00.000000000 +0100
247+++ vsftpd-2.2.2/clamav.h 2010-04-29 19:46:54.435448038 +0200
ba8b947d
MM
248@@ -0,0 +1,12 @@
249+#ifndef _CLAMAV_H
250+#define _CLAMAV_H
251+
252+#include "str.h"
253+#include "session.h"
254+
255+extern int av_init();
256+extern int av_will_scan(const char *filename);
257+extern int av_init_scanner (struct vsf_session* p_sess);
258+extern int av_scan_file(struct vsf_session* p_sess, struct mystr *filename, struct mystr *virname);
259+
260+#endif
48e27130
MM
261diff -Naru vsftpd-2.2.2.orig/main.c vsftpd-2.2.2/main.c
262--- vsftpd-2.2.2.orig/main.c 2009-07-18 07:55:53.000000000 +0200
263+++ vsftpd-2.2.2/main.c 2010-04-29 19:46:54.435448038 +0200
3fdda9c5 264@@ -64,7 +64,9 @@
ba8b947d
MM
265 /* Secure connection state */
266 0, 0, 0, 0, 0, INIT_MYSTR, 0, -1, -1,
267 /* Login fails */
268- 0
269+ 0,
270+ /* av */
271+ -1, INIT_MYSTR
272 };
48e27130
MM
273 int config_loaded = 0;
274 int i;
275diff -Naru vsftpd-2.2.2.orig/parseconf.c vsftpd-2.2.2/parseconf.c
276--- vsftpd-2.2.2.orig/parseconf.c 2009-08-07 20:46:40.000000000 +0200
277+++ vsftpd-2.2.2/parseconf.c 2010-04-29 19:46:54.435448038 +0200
278@@ -100,6 +100,7 @@
3fdda9c5 279 { "delete_failed_uploads", &tunable_delete_failed_uploads },
ba8b947d
MM
280 { "implicit_ssl", &tunable_implicit_ssl },
281 { "sandbox", &tunable_sandbox },
ba8b947d 282+ { "av_enable", &tunable_av_enable },
3fdda9c5
MM
283 { "require_ssl_reuse", &tunable_require_ssl_reuse },
284 { "isolate", &tunable_isolate },
48e27130
MM
285 { "isolate_network", &tunable_isolate_network },
286@@ -133,6 +134,7 @@
ba8b947d
MM
287 { "delay_successful_login", &tunable_delay_successful_login },
288 { "max_login_fails", &tunable_max_login_fails },
289 { "chown_upload_mode", &tunable_chown_upload_mode },
290+ { "av_clamd_port", &tunable_av_clamd_port },
291 { 0, 0 }
292 };
293
48e27130 294@@ -175,6 +177,10 @@
ba8b947d
MM
295 { "dsa_private_key_file", &tunable_dsa_private_key_file },
296 { "ca_certs_file", &tunable_ca_certs_file },
297 { "cmds_denied", &tunable_cmds_denied },
298+ { "av_clamd_socket", &tunable_av_clamd_socket },
299+ { "av_clamd_host", &tunable_av_clamd_host },
300+ { "av_include_files", &tunable_av_include_files },
301+ { "av_exclude_files", &tunable_av_exclude_files },
302 { 0, 0 }
303 };
304
48e27130
MM
305diff -Naru vsftpd-2.2.2.orig/postlogin.c vsftpd-2.2.2/postlogin.c
306--- vsftpd-2.2.2.orig/postlogin.c 2009-11-07 05:55:12.000000000 +0100
307+++ vsftpd-2.2.2/postlogin.c 2010-04-29 19:46:54.438781445 +0200
ba8b947d
MM
308@@ -27,6 +27,7 @@
309 #include "ssl.h"
310 #include "vsftpver.h"
311 #include "opts.h"
312+#include "clamav.h"
313
314 /* Private local functions */
315 static void handle_pwd(struct vsf_session* p_sess);
48e27130 316@@ -972,12 +973,15 @@
ba8b947d
MM
317 static struct vsf_sysutil_statbuf* s_p_statbuf;
318 static struct mystr s_filename;
319 struct mystr* p_filename;
320+ struct mystr tmp_filename = INIT_MYSTR;
321 struct vsf_transfer_ret trans_ret;
322 int new_file_fd;
323+ int av_orig_file_fd = -1;
324 int remote_fd;
325 int success = 0;
326 int created = 0;
327 int do_truncate = 0;
328+ int do_av = 0;
329 filesize_t offset = p_sess->restart_pos;
330 p_sess->restart_pos = 0;
331 if (!data_transfer_checks_ok(p_sess))
48e27130 332@@ -991,6 +995,7 @@
ba8b947d
MM
333 get_unique_filename(&s_filename, p_filename);
334 p_filename = &s_filename;
335 }
336+
337 vsf_log_start_entry(p_sess, kVSFLogEntryUpload);
338 str_copy(&p_sess->log_str, &p_sess->ftp_arg_str);
339 prepend_path_to_filename(&p_sess->log_str);
48e27130 340@@ -1022,6 +1027,24 @@
ba8b947d
MM
341 return;
342 }
343 created = 1;
344+
345+ if (av_will_scan(str_getbuf(p_filename))) {
346+ do_av = 1;
347+ str_copy(&tmp_filename, p_filename);
348+ str_append_text(&tmp_filename, ".XXXXXX");
349+ av_orig_file_fd = new_file_fd;
350+ /* FIXME: various permissions issues... ex. writable file in non-writable directory */
351+ new_file_fd = mkstemp(str_getbuf(&tmp_filename));
352+ if (vsf_sysutil_retval_is_error(new_file_fd))
353+ {
354+ vsf_sysutil_close(av_orig_file_fd);
355+ vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create temp file.");
356+ return;
357+ }
358+ /* mkstemp creates file with 0600 */
359+ vsf_sysutil_fchmod(new_file_fd, 0666 &(~vsf_sysutil_get_umask()));
360+ }
361+
362 vsf_sysutil_fstat(new_file_fd, &s_p_statbuf);
363 if (vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
364 {
48e27130 365@@ -1047,6 +1070,8 @@
ba8b947d
MM
366 if (tunable_lock_upload_files)
367 {
368 vsf_sysutil_lock_file_write(new_file_fd);
369+ if (do_av)
370+ vsf_sysutil_lock_file_write(av_orig_file_fd);
371 }
372 /* Must truncate the file AFTER locking it! */
373 if (do_truncate)
48e27130 374@@ -1054,6 +1079,22 @@
ba8b947d
MM
375 vsf_sysutil_ftruncate(new_file_fd);
376 vsf_sysutil_lseek_to(new_file_fd, 0);
377 }
378+ if (do_av && (is_append || offset != 0)) {
379+ char buf[4096];
380+ int count;
381+
382+ /* copy original file */
383+ vsf_sysutil_lseek_to(av_orig_file_fd, 0);
384+ while ((count=vsf_sysutil_read(av_orig_file_fd, buf, 4096)) > 0) {
385+ if (vsf_sysutil_write_loop(new_file_fd, buf, count) < 0) {
386+ vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not copy temp file.");
387+ vsf_sysutil_close(new_file_fd);
388+ vsf_sysutil_close(av_orig_file_fd);
389+ vsf_sysutil_unlink(str_getbuf(&tmp_filename));
390+ return;
391+ }
392+ }
393+ }
394 if (!is_append && offset != 0)
395 {
396 /* XXX - warning, allows seek past end of file! Check for seek > size? */
48e27130 397@@ -1077,6 +1118,7 @@
ba8b947d
MM
398 }
399 if (vsf_sysutil_retval_is_error(remote_fd))
400 {
401+ vsf_sysutil_unlink(str_getbuf(&tmp_filename));
402 goto port_pasv_cleanup_out;
403 }
404 if (tunable_ascii_upload_enable && p_sess->is_ascii)
48e27130 405@@ -1097,7 +1139,6 @@
ba8b947d
MM
406 if (trans_ret.retval == 0)
407 {
408 success = 1;
409- vsf_log_do_log(p_sess, 1);
410 }
411 if (trans_ret.retval == -1)
412 {
48e27130 413@@ -1109,7 +1150,43 @@
ba8b947d
MM
414 }
415 else
416 {
2e845366 417- vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "Transfer complete.");
ba8b947d
MM
418+ if (do_av) {
419+ struct mystr virname = INIT_MYSTR;
420+ struct mystr resp_str = INIT_MYSTR;
421+
422+ switch (av_scan_file(p_sess, &tmp_filename, &virname)) {
423+ case 1:
424+ str_alloc_text(&resp_str, "Virus found: ");
425+ str_append_str(&resp_str, &virname);
426+ vsf_log_line(p_sess, kVSFLogEntryUpload, &resp_str);
427+ vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, str_getbuf(&resp_str));
428+ str_free(&resp_str);
429+
430+ str_unlink(&tmp_filename);
431+ break;
432+ case 2:
433+ vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure scanning file.");
434+ str_unlink(&tmp_filename);
435+ break;
436+ default:
437+ /* FIXME: race condition */
438+ if (vsf_sysutil_rename(str_getbuf(&tmp_filename), str_getbuf(p_filename)) < 0) {
439+ vsf_cmdio_write(p_sess, FTP_BADSENDFILE, "Failure writing to local file .");
440+ str_unlink(&tmp_filename);
441+ }
442+ else
443+ {
444+ vsf_log_do_log(p_sess, 1);
445+ vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
446+ }
447+ break;
448+ }
449+ }
450+ else
451+ {
452+ vsf_log_do_log(p_sess, 1);
453+ vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
454+ }
455 }
456 check_abor(p_sess);
457 port_pasv_cleanup_out:
48e27130 458@@ -1117,9 +1194,15 @@
ba8b947d
MM
459 pasv_cleanup(p_sess);
460 if (tunable_delete_failed_uploads && created && !success)
461 {
462- str_unlink(p_filename);
463+ if (do_av) {
464+ str_unlink(&tmp_filename);
465+ } else {
466+ str_unlink(p_filename);
467+ }
468 }
469 vsf_sysutil_close(new_file_fd);
470+ if (do_av)
471+ vsf_sysutil_close(av_orig_file_fd);
472 }
473
474 static void
48e27130 475@@ -1898,3 +1981,5 @@
ba8b947d
MM
476 {
477 vsf_cmdio_write(p_sess, FTP_LOGINOK, "Already logged in.");
478 }
479+
480+// vim: sw=2:
48e27130
MM
481diff -Naru vsftpd-2.2.2.orig/secutil.c vsftpd-2.2.2/secutil.c
482--- vsftpd-2.2.2.orig/secutil.c 2009-05-27 08:20:36.000000000 +0200
483+++ vsftpd-2.2.2/secutil.c 2010-04-29 19:46:54.438781445 +0200
ba8b947d
MM
484@@ -34,6 +34,7 @@
485 if (p_dir_str == 0 || str_isempty(p_dir_str))
486 {
487 str_alloc_text(&dir_str, vsf_sysutil_user_get_homedir(p_user));
488+ str_copy(p_dir_str, &dir_str);
489 }
490 else
491 {
48e27130
MM
492diff -Naru vsftpd-2.2.2.orig/session.h vsftpd-2.2.2/session.h
493--- vsftpd-2.2.2.orig/session.h 2008-02-12 03:39:38.000000000 +0100
494+++ vsftpd-2.2.2/session.h 2010-04-29 19:46:54.438781445 +0200
ba8b947d
MM
495@@ -93,6 +93,10 @@
496 int ssl_slave_fd;
497 int ssl_consumer_fd;
498 unsigned int login_fails;
499+
500+ /* data for av scanner */
501+ int clamd_sock;
502+ struct mystr chroot_str;
503 };
504
505 #endif /* VSF_SESSION_H */
48e27130
MM
506diff -Naru vsftpd-2.2.2.orig/tunables.c vsftpd-2.2.2/tunables.c
507--- vsftpd-2.2.2.orig/tunables.c 2009-07-15 22:08:27.000000000 +0200
508+++ vsftpd-2.2.2/tunables.c 2010-04-29 19:48:44.265437093 +0200
509@@ -85,6 +85,8 @@
3fdda9c5 510 int tunable_isolate;
48e27130 511 int tunable_isolate_network;
ba8b947d
MM
512
513+int tunable_av_enable;
514+
515 unsigned int tunable_accept_timeout;
516 unsigned int tunable_connect_timeout;
517 unsigned int tunable_local_umask;
48e27130 518@@ -105,6 +107,7 @@
ba8b947d
MM
519 unsigned int tunable_delay_successful_login;
520 unsigned int tunable_max_login_fails;
521 unsigned int tunable_chown_upload_mode;
522+unsigned int tunable_av_clamd_port;
523
524 const char* tunable_secure_chroot_dir;
525 const char* tunable_ftp_username;
48e27130 526@@ -139,6 +142,11 @@
ba8b947d
MM
527 const char* tunable_dsa_private_key_file;
528 const char* tunable_ca_certs_file;
529
530+const char* tunable_av_clamd_socket;
531+const char* tunable_av_clamd_host;
532+const char* tunable_av_include_files;
533+const char* tunable_av_exclude_files;
534+
535 static void install_str_setting(const char* p_value, const char** p_storage);
536
537 void
98b47603 538@@ -219,9 +227,10 @@
ba8b947d
MM
539 tunable_sandbox = 0;
540 tunable_require_ssl_reuse = 1;
3fdda9c5 541 tunable_isolate = 1;
48e27130
MM
542- tunable_isolate_network = 1;
543+ tunable_isolate_network = 0;
98b47603
AG
544 tunable_ftp_enable = 1;
545 tunable_http_enable = 0;
48e27130 546+ tunable_av_enable = 0;
ba8b947d
MM
547
548 tunable_accept_timeout = 60;
48e27130
MM
549 tunable_connect_timeout = 60;
550@@ -245,6 +254,7 @@
ba8b947d
MM
551 tunable_max_login_fails = 3;
552 /* -rw------- */
553 tunable_chown_upload_mode = 0600;
554+ tunable_av_clamd_port = 3310;
555
556 install_str_setting("/usr/share/empty", &tunable_secure_chroot_dir);
557 install_str_setting("ftp", &tunable_ftp_username);
48e27130 558@@ -280,6 +290,11 @@
ba8b947d
MM
559 install_str_setting(0, &tunable_rsa_private_key_file);
560 install_str_setting(0, &tunable_dsa_private_key_file);
561 install_str_setting(0, &tunable_ca_certs_file);
562+
563+ install_str_setting(0, &tunable_av_clamd_socket);
564+ install_str_setting("127.0.0.1", &tunable_av_clamd_host);
565+ install_str_setting(0, &tunable_av_include_files);
566+ install_str_setting(0, &tunable_av_exclude_files);
567 }
568
569 void
48e27130
MM
570diff -Naru vsftpd-2.2.2.orig/tunables.h vsftpd-2.2.2/tunables.h
571--- vsftpd-2.2.2.orig/tunables.h 2009-07-07 03:37:28.000000000 +0200
572+++ vsftpd-2.2.2/tunables.h 2010-04-29 19:46:54.438781445 +0200
ba8b947d
MM
573@@ -83,6 +83,7 @@
574 extern int tunable_implicit_ssl; /* Use implicit SSL protocol */
575 extern int tunable_sandbox; /* Deploy ptrace sandbox */
576 extern int tunable_require_ssl_reuse; /* Require re-used data conn */
577+extern int tunable_av_enable; /* Scan av incomming files */
3fdda9c5 578 extern int tunable_isolate; /* Use container clone() flags */
48e27130 579 extern int tunable_isolate_network; /* Use CLONE_NEWNET */
ba8b947d 580
48e27130 581@@ -107,6 +108,7 @@
ba8b947d
MM
582 extern unsigned int tunable_delay_successful_login;
583 extern unsigned int tunable_max_login_fails;
584 extern unsigned int tunable_chown_upload_mode;
585+extern unsigned int tunable_av_clamd_port;
586
587 /* String defines */
588 extern const char* tunable_secure_chroot_dir;
48e27130 589@@ -141,6 +143,10 @@
ba8b947d
MM
590 extern const char* tunable_dsa_private_key_file;
591 extern const char* tunable_ca_certs_file;
592 extern const char* tunable_cmds_denied;
593+extern const char* tunable_av_clamd_socket;
594+extern const char* tunable_av_clamd_host;
595+extern const char* tunable_av_include_files;
596+extern const char* tunable_av_exclude_files;
597
598 #endif /* VSF_TUNABLES_H */
599
48e27130
MM
600diff -Naru vsftpd-2.2.2.orig/twoprocess.c vsftpd-2.2.2/twoprocess.c
601--- vsftpd-2.2.2.orig/twoprocess.c 2009-07-18 07:56:44.000000000 +0200
602+++ vsftpd-2.2.2/twoprocess.c 2010-04-29 19:46:54.438781445 +0200
603@@ -428,6 +428,13 @@
ba8b947d
MM
604 p_user_str, p_orig_user_str);
605 vsf_secutil_change_credentials(p_user_str, &userdir_str, &chroot_str,
606 0, secutil_option);
607+
608+ if (do_chroot) {
609+ str_copy(&p_sess->chroot_str, &userdir_str);
610+ } else {
611+ str_empty(&p_sess->chroot_str);
612+ }
613+
614 if (!str_isempty(&chdir_str))
615 {
616 (void) str_chdir(&chdir_str);
48e27130
MM
617diff -Naru vsftpd-2.2.2.orig/vsftpd.conf.5 vsftpd-2.2.2/vsftpd.conf.5
618--- vsftpd-2.2.2.orig/vsftpd.conf.5 2009-10-19 04:46:30.000000000 +0200
619+++ vsftpd-2.2.2/vsftpd.conf.5 2010-04-29 19:46:54.438781445 +0200
ba8b947d
MM
620@@ -105,6 +105,11 @@
621
622 Default: NO
623 .TP
624+.B av_enable
625+If enabled, all uploaded files are scanned with clamav (through clamd).
626+
627+Default: NO
628+.TP
629 .B background
630 When enabled, and vsftpd is started in "listen" mode, vsftpd will background
631 the listener process. i.e. control will immediately be returned to the shell
3fdda9c5 632@@ -643,6 +648,11 @@
ba8b947d
MM
633
634 Default: 077
635 .TP
636+.B av_clamd_port
637+Port number where clamd listen on.
638+
639+Default: 3310
640+.TP
641 .B chown_upload_mode
642 The file mode to force for chown()ed anonymous uploads. (Added in v2.0.6).
643
3fdda9c5 644@@ -758,6 +768,18 @@
ba8b947d
MM
645
646 Default: (none)
647 .TP
648+.B av_clamd_host
649+IP where clamd listen. It must be on the same host (or have access to same
650+filesystem).
651+
652+Default: 127.0.0.1
653+.TP
654+.B av_clamd_socket
655+UNIX socket of clamd. Warning: When using chroot you should use TCP instead of
656+UNIX socket.
657+
658+Default: (none)
659+.TP
660 .B banned_email_file
661 This option is the name of a file containing a list of anonymous e-mail
662 passwords which are not permitted. This file is consulted if the option
This page took 0.164324 seconds and 4 git commands to generate.