]> git.pld-linux.org Git - packages/vsftpd.git/blame - vsftpd-clamav.patch
- applied upstream
[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
8diff -Nru vsftpd-2.1.0.orig/Makefile vsftpd-2.1.0/Makefile
9--- vsftpd-2.1.0.orig/Makefile 2009-02-18 23:28:05.000000000 +0100
10+++ vsftpd-2.1.0/Makefile 2009-05-08 19:32:07.000000000 +0200
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:
20diff -Nru vsftpd-2.1.0.orig/clamav.c vsftpd-2.1.0/clamav.c
21--- vsftpd-2.1.0.orig/clamav.c 1970-01-01 01:00:00.000000000 +0100
22+++ vsftpd-2.1.0/clamav.c 2009-05-08 19:32:07.000000000 +0200
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+
245diff -Nru vsftpd-2.1.0.orig/clamav.h vsftpd-2.1.0/clamav.h
246--- vsftpd-2.1.0.orig/clamav.h 1970-01-01 01:00:00.000000000 +0100
247+++ vsftpd-2.1.0/clamav.h 2009-05-08 19:32:07.000000000 +0200
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
261diff -Nru vsftpd-2.1.0.orig/main.c vsftpd-2.1.0/main.c
262--- vsftpd-2.1.0.orig/main.c 2009-01-07 22:50:42.000000000 +0100
263+++ vsftpd-2.1.0/main.c 2009-05-08 19:32:07.000000000 +0200
264@@ -65,7 +65,9 @@
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 };
273 int config_specified = 0;
274 const char* p_config_name = VSFTP_DEFAULT_CONFIG;
275diff -Nru vsftpd-2.1.0.orig/parseconf.c vsftpd-2.1.0/parseconf.c
276--- vsftpd-2.1.0.orig/parseconf.c 2008-12-18 07:21:41.000000000 +0100
277+++ vsftpd-2.1.0/parseconf.c 2009-05-08 19:32:07.000000000 +0200
278@@ -106,6 +106,7 @@
279 { "implicit_ssl", &tunable_implicit_ssl },
280 { "sandbox", &tunable_sandbox },
281 { "require_ssl_reuse", &tunable_require_ssl_reuse },
282+ { "av_enable", &tunable_av_enable },
283 { 0, 0 }
284 };
285
286@@ -136,6 +137,7 @@
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
294@@ -178,6 +180,10 @@
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
305diff -Nru vsftpd-2.1.0.orig/postlogin.c vsftpd-2.1.0/postlogin.c
306--- vsftpd-2.1.0.orig/postlogin.c 2008-12-19 05:20:48.000000000 +0100
307+++ vsftpd-2.1.0/postlogin.c 2009-05-08 19:32:07.000000000 +0200
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);
316@@ -1007,12 +1008,15 @@
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))
332@@ -1026,6 +1030,7 @@
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);
340@@ -1057,6 +1062,24 @@
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 {
365@@ -1082,6 +1105,8 @@
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)
374@@ -1089,6 +1114,22 @@
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? */
397@@ -1112,6 +1153,7 @@
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)
405@@ -1132,7 +1174,6 @@
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 {
413@@ -1144,7 +1185,43 @@
414 }
415 else
416 {
417- vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
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:
458@@ -1152,9 +1229,15 @@
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
475@@ -1931,3 +2014,5 @@
476 {
477 vsf_cmdio_write(p_sess, FTP_LOGINOK, "Already logged in.");
478 }
479+
480+// vim: sw=2:
481diff -Nru vsftpd-2.1.0.orig/secutil.c vsftpd-2.1.0/secutil.c
482--- vsftpd-2.1.0.orig/secutil.c 2008-02-02 02:30:40.000000000 +0100
483+++ vsftpd-2.1.0/secutil.c 2009-05-08 19:32:07.000000000 +0200
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 {
492diff -Nru vsftpd-2.1.0.orig/session.h vsftpd-2.1.0/session.h
493--- vsftpd-2.1.0.orig/session.h 2008-02-12 03:39:38.000000000 +0100
494+++ vsftpd-2.1.0/session.h 2009-05-08 19:32:07.000000000 +0200
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 */
506diff -Nru vsftpd-2.1.0.orig/tunables.c vsftpd-2.1.0/tunables.c
507--- vsftpd-2.1.0.orig/tunables.c 2008-12-18 02:42:45.000000000 +0100
508+++ vsftpd-2.1.0/tunables.c 2009-05-08 19:32:07.000000000 +0200
509@@ -83,6 +83,8 @@
510 int tunable_sandbox;
511 int tunable_require_ssl_reuse;
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;
518@@ -103,6 +105,7 @@
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;
526@@ -137,6 +140,11 @@
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
538@@ -216,6 +224,7 @@
539 tunable_implicit_ssl = 0;
540 tunable_sandbox = 0;
541 tunable_require_ssl_reuse = 1;
542+ tunable_av_enable = 0;
543
544 tunable_accept_timeout = 60;
545 tunable_connect_timeout = 60;
546@@ -241,6 +250,7 @@
547 tunable_max_login_fails = 3;
548 /* -rw------- */
549 tunable_chown_upload_mode = 0600;
550+ tunable_av_clamd_port = 3310;
551
552 install_str_setting("/usr/share/empty", &tunable_secure_chroot_dir);
553 install_str_setting("ftp", &tunable_ftp_username);
554@@ -276,6 +286,11 @@
555 install_str_setting(0, &tunable_rsa_private_key_file);
556 install_str_setting(0, &tunable_dsa_private_key_file);
557 install_str_setting(0, &tunable_ca_certs_file);
558+
559+ install_str_setting(0, &tunable_av_clamd_socket);
560+ install_str_setting("127.0.0.1", &tunable_av_clamd_host);
561+ install_str_setting(0, &tunable_av_include_files);
562+ install_str_setting(0, &tunable_av_exclude_files);
563 }
564
565 void
566diff -Nru vsftpd-2.1.0.orig/tunables.h vsftpd-2.1.0/tunables.h
567--- vsftpd-2.1.0.orig/tunables.h 2008-12-17 06:47:11.000000000 +0100
568+++ vsftpd-2.1.0/tunables.h 2009-05-08 19:32:07.000000000 +0200
569@@ -83,6 +83,7 @@
570 extern int tunable_implicit_ssl; /* Use implicit SSL protocol */
571 extern int tunable_sandbox; /* Deploy ptrace sandbox */
572 extern int tunable_require_ssl_reuse; /* Require re-used data conn */
573+extern int tunable_av_enable; /* Scan av incomming files */
574
575 /* Integer/numeric defines */
576 extern unsigned int tunable_accept_timeout;
577@@ -105,6 +106,7 @@
578 extern unsigned int tunable_delay_successful_login;
579 extern unsigned int tunable_max_login_fails;
580 extern unsigned int tunable_chown_upload_mode;
581+extern unsigned int tunable_av_clamd_port;
582
583 /* String defines */
584 extern const char* tunable_secure_chroot_dir;
585@@ -139,6 +141,10 @@
586 extern const char* tunable_dsa_private_key_file;
587 extern const char* tunable_ca_certs_file;
588 extern const char* tunable_cmds_denied;
589+extern const char* tunable_av_clamd_socket;
590+extern const char* tunable_av_clamd_host;
591+extern const char* tunable_av_include_files;
592+extern const char* tunable_av_exclude_files;
593
594 #endif /* VSF_TUNABLES_H */
595
596diff -Nru vsftpd-2.1.0.orig/twoprocess.c vsftpd-2.1.0/twoprocess.c
597--- vsftpd-2.1.0.orig/twoprocess.c 2009-01-15 02:03:04.000000000 +0100
598+++ vsftpd-2.1.0/twoprocess.c 2009-05-08 19:32:07.000000000 +0200
599@@ -356,6 +356,13 @@
600 p_user_str, p_orig_user_str);
601 vsf_secutil_change_credentials(p_user_str, &userdir_str, &chroot_str,
602 0, secutil_option);
603+
604+ if (do_chroot) {
605+ str_copy(&p_sess->chroot_str, &userdir_str);
606+ } else {
607+ str_empty(&p_sess->chroot_str);
608+ }
609+
610 if (!str_isempty(&chdir_str))
611 {
612 (void) str_chdir(&chdir_str);
613diff -Nru vsftpd-2.1.0.orig/vsftpd.conf.5 vsftpd-2.1.0/vsftpd.conf.5
614--- vsftpd-2.1.0.orig/vsftpd.conf.5 2008-12-18 02:44:21.000000000 +0100
615+++ vsftpd-2.1.0/vsftpd.conf.5 2009-05-08 19:42:35.000000000 +0200
616@@ -105,6 +105,11 @@
617
618 Default: NO
619 .TP
620+.B av_enable
621+If enabled, all uploaded files are scanned with clamav (through clamd).
622+
623+Default: NO
624+.TP
625 .B background
626 When enabled, and vsftpd is started in "listen" mode, vsftpd will background
627 the listener process. i.e. control will immediately be returned to the shell
628@@ -640,6 +645,11 @@
629
630 Default: 077
631 .TP
632+.B av_clamd_port
633+Port number where clamd listen on.
634+
635+Default: 3310
636+.TP
637 .B chown_upload_mode
638 The file mode to force for chown()ed anonymous uploads. (Added in v2.0.6).
639
640@@ -755,6 +765,18 @@
641
642 Default: (none)
643 .TP
644+.B av_clamd_host
645+IP where clamd listen. It must be on the same host (or have access to same
646+filesystem).
647+
648+Default: 127.0.0.1
649+.TP
650+.B av_clamd_socket
651+UNIX socket of clamd. Warning: When using chroot you should use TCP instead of
652+UNIX socket.
653+
654+Default: (none)
655+.TP
656 .B banned_email_file
657 This option is the name of a file containing a list of anonymous e-mail
658 passwords which are not permitted. This file is consulted if the option
This page took 0.258055 seconds and 4 git commands to generate.