]> git.pld-linux.org Git - packages/vsftpd.git/blob - vsftpd-clamav.patch
- rel.2: allow ssl build on AC - changed sha256 to sha1 (less secure but
[packages/vsftpd.git] / vsftpd-clamav.patch
1 Add support for scanning uploaded files with clamav. Not all features are 
2 implemented (ex. file inclusion/exclusion for scanning). Every uploaded file is
3 saved in random named file, and moved to destination file after scanning. Side
4 effects: when uploaded *new* file was infected, 0-size file left.
5
6 Written by Marek Marczykowski <m.marczykowski@fiok.pl>
7
8 diff -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
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:
20 diff -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
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 +
245 diff -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
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
261 diff -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
264 @@ -64,7 +64,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_loaded = 0;
274    int i;
275 diff -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 @@
279    { "delete_failed_uploads", &tunable_delete_failed_uploads },
280    { "implicit_ssl", &tunable_implicit_ssl },
281    { "sandbox", &tunable_sandbox },
282 +  { "av_enable", &tunable_av_enable },
283    { "require_ssl_reuse", &tunable_require_ssl_reuse },
284    { "isolate", &tunable_isolate },
285    { "isolate_network", &tunable_isolate_network },
286 @@ -133,6 +134,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 @@ -175,6 +177,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  
305 diff -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
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 @@ -972,12 +973,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 @@ -991,6 +995,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 @@ -1022,6 +1027,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 @@ -1047,6 +1070,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 @@ -1054,6 +1079,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 @@ -1077,6 +1118,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 @@ -1097,7 +1139,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 @@ -1109,7 +1150,43 @@
414    }
415    else
416    {
417 -    vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "Transfer complete.");
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 @@ -1117,9 +1194,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 @@ -1898,3 +1981,5 @@
476  {
477    vsf_cmdio_write(p_sess, FTP_LOGINOK, "Already logged in.");
478  }
479 +
480 +// vim: sw=2:
481 diff -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
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      {
492 diff -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
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 */
506 diff -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 @@
510  int tunable_isolate;
511  int tunable_isolate_network;
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 @@ -105,6 +107,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 @@ -139,6 +142,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 @@ -219,9 +227,10 @@
539    tunable_sandbox = 0;
540    tunable_require_ssl_reuse = 1;
541    tunable_isolate = 1;
542 -  tunable_isolate_network = 1;
543 +  tunable_isolate_network = 0;
544    tunable_ftp_enable = 1;
545    tunable_http_enable = 0;
546 +  tunable_av_enable = 0;
547  
548    tunable_accept_timeout = 60;
549    tunable_connect_timeout = 60;
550 @@ -245,6 +254,7 @@
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);
558 @@ -280,6 +290,11 @@
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
570 diff -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
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 */
578  extern int tunable_isolate;                   /* Use container clone() flags */
579  extern int tunable_isolate_network;           /* Use CLONE_NEWNET */
580  
581 @@ -107,6 +108,7 @@
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;
589 @@ -141,6 +143,10 @@
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  
600 diff -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 @@
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);
617 diff -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
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
632 @@ -643,6 +648,11 @@
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  
644 @@ -758,6 +768,18 @@
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.189192 seconds and 3 git commands to generate.