debian/ 0000755 0000000 0000000 00000000000 12213721245 007165 5 ustar debian/watch 0000644 0000000 0000000 00000000142 11645322134 010215 0 ustar version=3
http://www.thrallingpenguin.com/resources/mod_clamav.htm mod_clamav-([\d\.]+)\.tar\.gz
debian/templates/ 0000755 0000000 0000000 00000000000 11645322134 011165 5 ustar debian/templates/clamav.conf 0000644 0000000 0000000 00000000160 11645322134 013274 0 ustar
ClamAV on
ClamServer localhost
ClamPort 3310
ClamMaxSize 250 Mb
debian/proftpd-mod-clamav.links 0000644 0000000 0000000 00000000125 11645322134 013723 0 ustar usr/share/doc/proftpd-mod-clamav/clamav.conf usr/share/proftpd/templates/clamav.conf
debian/proftpd-mod-clamav.install 0000644 0000000 0000000 00000000077 11645322134 014257 0 ustar debian/templates/clamav.conf usr/share/doc/proftpd-mod-clamav/
debian/rules 0000755 0000000 0000000 00000001166 11645322134 010253 0 ustar #!/usr/bin/make -f
# -*- makefile -*-
export DH_VERBOSE=1
MODULE_NAME=mod_clamav
DEBNAME=proftpd-mod-clamav
%:
dh $@
override_dh_auto_build:
DESTDIR=$(CURDIR)/debian/$(DEBNAME) prxs -c $(MODULE_NAME).c
override_dh_auto_install:
DESTDIR=$(CURDIR)/debian/$(DEBNAME) prxs -i -c $(MODULE_NAME).c
rm -f $(CURDIR)/debian/$(DEBNAME)/usr/lib/proftpd/*.la \
$(CURDIR)/debian/$(DEBNAME)/usr/lib/proftpd/*.a
override_dh_gencontrol:
cat /usr/share/proftpd/proftpd-substvars >> $(CURDIR)/debian/$(DEBNAME).substvars
dh_gencontrol
override_dh_autoclean:
DESTDIR=$(CURDIR)/debian/$(DEBNAME) prxs -d $(MODULE_NAME).c
debian/README.Debian 0000644 0000000 0000000 00000000433 11645322134 011230 0 ustar Add-on mod_clamav module for ProFTPD in Debian
----------------------------------------------
Note that the Debian version of this module is patched to avoid changing
the mod_core ProFTPD module and to work better with mod_sftp. Thanks
TJ Saunders and the ProFTPD team about that.
debian/proftpd-mod-clamav.dirs 0000644 0000000 0000000 00000000054 11645322134 013545 0 ustar usr/lib/proftpd
usr/share/proftpd/templates
debian/copyright 0000644 0000000 0000000 00000002174 11645322134 011126 0 ustar Format: http://dep.debian.net/deps/dep5/
Upstream-Name: mod_clamav
Upstream-Contact: Joseph Benden
Source: http://www.thrallingpenguin.com/resources/mod_clamav.htm
Files: *
Copyright: 2007-2010, Joseph Benden
License: GPL-2+
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
Files: debian/*
Copyright: 2011, Mahyuddin Susanto
License: GPL-2+
debian/source/ 0000755 0000000 0000000 00000000000 11645322134 010467 5 ustar debian/source/format 0000644 0000000 0000000 00000000014 11645322134 011675 0 ustar 3.0 (quilt)
debian/patches/ 0000755 0000000 0000000 00000000000 11645322134 010616 5 ustar debian/patches/cleanup 0000644 0000000 0000000 00000026563 11645322134 012204 0 ustar Index: proftpd-mod-clamav/mod_clamav.c
===================================================================
--- proftpd-mod-clamav.orig/mod_clamav.c 2011-04-20 17:38:03.000000000 +0200
+++ proftpd-mod-clamav/mod_clamav.c 2011-10-12 15:30:48.000000000 +0200
@@ -29,12 +29,12 @@
#include "conf.h"
#include "privs.h"
#include
-#include "mod_clamav.h"
/**
* Module version and declaration
*/
#define MOD_CLAMAV_VERSION "mod_clamav/0.10"
+
module clamav_module;
/**
@@ -50,11 +50,13 @@
* Local declarations
*/
static unsigned long parse_nbytes(char *nbytes_str, char *units_str);
+static int clamavd_connect(void);
+static int clamavd_scan(int, const char *, const char *);
/**
* Read the returned information from Clamavd.
*/
-int clamavd_result(int sockd, const char *abs_filename, const char *rel_filename) {
+static int clamavd_result(int sockd, const char *abs_filename, const char *rel_filename) {
int infected = 0, waserror = 0, ret;
char buff[4096], *pt, *pt1;
FILE *fd = 0;
@@ -65,15 +67,26 @@
errno);
return -1;
}
-
- if (fgets(buff, sizeof(buff), fd)) {
+
+ memset(buff, '\0', sizeof(buff));
+ if (fgets(buff, sizeof(buff)-1, fd)) {
if (strstr(buff, "FOUND\n")) {
++infected;
-
- pt = strrchr(buff, ':');
- if (pt)
- *pt = 0;
-
+
+ /* Advance past the portion of the response,
+ * and the path name, and the colon and space that
+ * follow the path name.
+ */
+ pt = strchr(buff, ':');
+ pt++;
+ pt += strlen(abs_filename);
+ pt += 3;
+
+ pt1 = strchr(pt, '(');
+ if (pt1 != NULL) {
+ *pt1 = '\0';
+ }
+
/* Delete the infected upload */
if ((ret=pr_fsio_unlink(rel_filename))!=0) {
pr_log_pri(PR_LOG_ERR,
@@ -81,20 +94,14 @@
errno, strerror(errno));
}
- /* clean up the response */
- pt += 2;
- pt1 = strstr(pt, " FOUND");
- if (pt1) {
- *pt1 = 0;
- }
-
/* Inform the client the file contained a virus */
pr_response_add_err(R_550, "Virus Detected and Removed: %s", pt);
/* Log the fact */
pr_log_pri(PR_LOG_ERR,
MOD_CLAMAV_VERSION ": Virus '%s' found in '%s'", pt, abs_filename);
- } else if (strstr(buff, "ERROR\n")) {
+ } else if (strstr(buff, "ERROR\n") != NULL ||
+ strstr(buff, "UNKNOWN COMMAND") != NULL) {
pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": Clamd Error: %s", buff);
waserror = 1;
}
@@ -106,8 +113,8 @@
/**
* Start a session with Clamavd.
*/
-int clamavd_session_start(int sockd) {
- if (sockd != -1 && write(sockd, "SESSION\n", 8) <= 0) {
+static int clamavd_session_start(int sockd) {
+ if (sockd != -1 && write(sockd, "nIDSESSION\n", 11) <= 0) {
pr_log_pri(PR_LOG_ERR,
MOD_CLAMAV_VERSION ": error: Clamd didn't accept the session request.");
return -1;
@@ -118,8 +125,8 @@
/**
* End session.
*/
-int clamavd_session_stop(int sockd) {
- if (sockd != -1 && write(sockd, "END\n", 4) <= 0) {
+static int clamavd_session_stop(int sockd) {
+ if (sockd != -1 && write(sockd, "nEND\n", 5) <= 0) {
pr_log_pri(PR_LOG_INFO,
MOD_CLAMAV_VERSION ": info: Clamd didn't accept the session end request.");
return -1;
@@ -130,7 +137,7 @@
/**
* Test the connection with Clamd.
*/
-int clamavd_connect_check(int sockd) {
+static int clamavd_connect_check(int sockd) {
FILE *fd = NULL;
char buff[32];
@@ -138,8 +145,8 @@
return 0;
if (write(sockd, "PING\n", 5) <= 0) {
- pr_log_debug(DEBUG4, "Clamd did not accept PING (%d): %s",
- errno, strerror(errno));
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION
+ ": Clamd did not accept PING (%d): %s", errno, strerror(errno));
close(sockd);
clamd_sockd = -1;
clam_errno = errno;
@@ -147,7 +154,7 @@
}
if ((fd = fdopen(dup(sockd), "r")) == NULL) {
- pr_log_debug(DEBUG4, "Clamd can not open descriptor for reading (%d): %s",
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": Clamd can not open descriptor for reading (%d): %s",
errno, strerror(errno));
close(sockd);
clamd_sockd = -1;
@@ -160,10 +167,10 @@
fclose(fd);
return 1;
}
- pr_log_debug(DEBUG4, "Clamd return unknown response to PING: '%s'", buff);
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": Clamd return unknown response to PING: '%s'", buff);
}
- pr_log_debug(DEBUG4, "Clamd did not respond to fgets (%d): %s", errno, strerror(errno));
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": Clamd did not respond to fgets (%d): %s", errno, strerror(errno));
fclose(fd);
close(sockd);
clamd_sockd = -1;
@@ -174,7 +181,7 @@
/**
* Request Clamavd to perform a scan.
*/
-int clamavd_scan(int sockd, const char *abs_filename, const char *rel_filename) {
+static int clamavd_scan(int sockd, const char *abs_filename, const char *rel_filename) {
char *scancmd = NULL;
scancmd = calloc(strlen(abs_filename) + 20, sizeof(char));
@@ -183,22 +190,24 @@
return -1;
}
- sprintf(scancmd, "SCAN %s\n", abs_filename);
+ sprintf(scancmd, "nSCAN %s\n", abs_filename);
if (!clamavd_connect_check(sockd)) {
if ((clamd_sockd = clamavd_connect()) < 0) {
pr_log_pri(PR_LOG_ERR,
MOD_CLAMAV_VERSION ": error: Cannot re-connect to Clamd (%d): %s",
errno, strerror(errno));
+ free(scancmd);
+ scancmd = NULL;
clam_errno = errno;
return -1;
}
clamavd_session_start(clamd_sockd);
sockd = clamd_sockd;
- pr_log_debug(DEBUG4, "Successfully reconnected to Clamd.");
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": Successfully reconnected to Clamd");
clam_errno = 0;
}
-
+
if (write(sockd, scancmd, strlen(scancmd)) <= 0) {
pr_log_pri(PR_LOG_ERR,
MOD_CLAMAV_VERSION ": error: Cannot write to the Clamd socket: %d", errno);
@@ -216,7 +225,7 @@
/**
* Connect a socket to ClamAVd.
*/
-int clamavd_connect(void) {
+static int clamavd_connect(void) {
struct sockaddr_un server;
struct sockaddr_in server2;
struct hostent *he;
@@ -314,61 +323,60 @@
return sockd;
}
-/**
- * Entry point of mod_xfer during an upload
- */
-int clamav_scan(cmd_rec *cmd) {
- char absolutepath[4096];
- char *file, *rel_file;
+static int clamav_fsio_close(pr_fh_t *fh, int fd) {
+ char *abs_path, *rel_path;
struct stat st;
+ int do_scan = FALSE;
config_rec *c = NULL;
unsigned long *minsize, *maxsize;
-
+
+ /* We're only interested in STOR, APPE, and maybe STOU commands. */
+ if (session.curr_cmd) {
+ if (strcmp(session.curr_cmd, C_STOR) == 0 ||
+ strcmp(session.curr_cmd, C_APPE) == 0 ||
+ strcmp(session.curr_cmd, C_STOU) == 0) {
+ do_scan = TRUE;
+ }
+ }
+
+ if (!do_scan) {
+ return close(fd);
+ }
+
+ /* Make sure the data is written to disk, so that the fstat(2) picks
+ * up the size properly.
+ */
+ if (fsync(fd) < 0) {
+ return -1;
+ }
+
+ pr_fs_clear_cache();
+ if (pr_fsio_fstat(fh, &st) < 0) {
+ return -1;
+ }
+
+ if (close(fd) < 0) {
+ return -1;
+ }
+
c = find_config(CURRENT_CONF, CONF_PARAM, "ClamAV", FALSE);
if (!c || !*(int*)(c->argv[0]))
return 0;
-
+
/**
* Figure out the absolute path of our directory
*/
- if (session.xfer.path && session.xfer.path_hidden) {
- /* Hidden Store Condition */
- if (session.chroot_path) {
- sstrncpy(absolutepath,
- pdircat(cmd->tmp_pool, session.chroot_path, session.xfer.path_hidden, NULL),
- sizeof(absolutepath) - 1);
- pr_log_debug(DEBUG4, "session.chroot_path is '%s'.", session.chroot_path);
- } else {
- sstrncpy(absolutepath, session.xfer.path_hidden, sizeof(absolutepath) - 1);
- }
- file = absolutepath;
- rel_file = session.xfer.path_hidden;
-
- pr_log_debug(DEBUG4, "session.xfer.path_hidden is '%s'.", session.xfer.path_hidden);
- } else if (session.xfer.path) {
-
- /* Default Condition */
- if (session.chroot_path) {
- sstrncpy(absolutepath, pdircat(cmd->tmp_pool, session.chroot_path, session.xfer.path, NULL),
- sizeof(absolutepath) - 1);
- pr_log_debug(DEBUG4, "session.chroot_path is '%s'.", session.chroot_path);
- } else {
- sstrncpy(absolutepath, session.xfer.path, sizeof(absolutepath) - 1);
- }
- file = absolutepath;
- rel_file = session.xfer.path;
-
- pr_log_debug(DEBUG4, "session.xfer.path is '%s'.", session.xfer.path);
+ if (session.chroot_path) {
+ abs_path = pdircat(fh->fh_pool, session.chroot_path, fh->fh_path, NULL);
} else {
-
- /* Error! */
- pr_log_pri(PR_LOG_ERR,
- MOD_CLAMAV_VERSION ": error: 'session.xfer.path' does not contain a valid filename.");
- pr_response_add_err(R_500, "'session.xfer.path' does not contain a valid filename.");
- return 1;
+ abs_path = pstrdup(fh->fh_pool, fh->fh_path);
}
-
+
+ rel_path = pstrdup(fh->fh_pool, fh->fh_path);
+
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": absolute path is '%s', relative path is '%s'", abs_path, rel_path);
+
/**
* Handle min/max settings
*/
@@ -384,18 +392,19 @@
if (clamd_minsize > 0 || clamd_maxsize > 0) {
/* Stat the file to acquire the size */
- if (pr_fsio_stat(rel_file, &st) == -1) {
+ pr_fs_clear_cache();
+ if (pr_fsio_fstat(fh, &st) == -1) {
pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Can not stat file (%d): %s", errno,
strerror(errno));
- return 1;
+ return -1;
}
- pr_log_debug(DEBUG4, "ClamMinSize=%lu ClamMaxSize=%lu Filesize=%" PR_LU, clamd_minsize, clamd_maxsize, (pr_off_t) st.st_size);
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": ClamMinSize=%lu ClamMaxSize=%lu Filesize=%" PR_LU, clamd_minsize, clamd_maxsize, (pr_off_t) st.st_size);
}
if (clamd_minsize > 0) {
/* test the minimum size */
if (st.st_size < clamd_minsize) {
- pr_log_debug(DEBUG4, "File is too small, skipping virus scan. min = %lu size = %" PR_LU,
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": File is too small, skipping virus scan. min = %lu size = %" PR_LU,
clamd_minsize, (pr_off_t) st.st_size);
return 0;
}
@@ -404,24 +413,25 @@
if (clamd_maxsize > 0) {
/* test the maximum size */
if (st.st_size > clamd_maxsize) {
- pr_log_debug(DEBUG4, "File is too large, skipping virus scan. max = %lu size = %" PR_LU,
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": File is too large, skipping virus scan. max = %lu size = %" PR_LU,
clamd_maxsize, (pr_off_t) st.st_size);
return 0;
}
}
- pr_log_debug(DEBUG4,
- "Going to virus scan absolute filename = '%s' with relative filename = '%s'.", file, rel_file);
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION
+ ": Going to virus scan absolute filename = '%s' with relative filename = '%s'.", abs_path, rel_path);
clam_errno = 0;
- if (clamavd_scan(clamd_sockd, file, rel_file) > 0) {
- return 1;
+ if (clamavd_scan(clamd_sockd, abs_path, rel_path) > 0) {
+ errno = EPERM;
+ return -1;
}
if (clam_errno == 0)
- pr_log_debug(DEBUG4, "No virus detected in filename = '%s'.", file);
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": No virus detected in filename = '%s'.", abs_path);
else
- pr_log_debug(DEBUG4, "Skipped virus scan due to errno = %d", clam_errno);
+ pr_log_debug(DEBUG4, MOD_CLAMAV_VERSION ": Skipped virus scan due to errno = %d", clam_errno);
return 0;
}
@@ -634,11 +644,17 @@
* Start FTP Session
*/
static int clamav_sess_init(void) {
-
+ pr_fs_t *fs;
+
is_remote = 0; clamd_sockd = -1;
pr_event_register(&clamav_module, "core.exit", clamav_shutdown, NULL);
-
+
+ fs = pr_register_fs(main_server->pool, "clamav", "/");
+ if (fs) {
+ fs->close = clamav_fsio_close;
+ }
+
return 0;
}
@@ -661,6 +677,7 @@
NULL,
NULL, /* auth function table */
NULL, /* init function */
- clamav_sess_init /* session init function */
+ clamav_sess_init, /* session init function */
+ MOD_CLAMAV_VERSION
};
debian/patches/series 0000644 0000000 0000000 00000000010 11645322134 012022 0 ustar cleanup
debian/compat 0000644 0000000 0000000 00000000002 11645322134 010365 0 ustar 7
debian/control 0000644 0000000 0000000 00000002317 11645322134 010575 0 ustar Source: proftpd-mod-clamav
Section: net
Priority: optional
Maintainer: ProFTPD Maintainance Team
Uploaders: Mahyuddin Susanto ,
Francesco Paolo Lovergine
DM-Upload-Allowed: yes
Build-Depends: autotools-dev,
debhelper (>= 7.0.50~),
libacl1-dev,
proftpd-dev (>= 1.3.3d-5~)
Standards-Version: 3.9.2
Homepage: http://www.thrallingpenguin.com/resources/mod_clamav.htm
Vcs-Git: git://git.debian.org/pkg-proftpd/proftpd-mod-clamav.git
Vcs-Browser: http://git.debian.org/?p=pkg-proftpd/proftpd-mod-clamav.git;a=summary
Package: proftpd-mod-clamav
Architecture: any
Depends: clamav, ${misc:Depends}, ${proftpd:Depends}, ${shlibs:Depends}
Description: ProFTPD module mod_clamav
Mod_Clamav can be configured to either use Clamd via local unix
sockets or TCP sockets. This allows one to combine ProFTPd with
Mod_Clamav and Clamd on a system with local unix sockets for minimal
administrative overhead and decent security. however, also allows for
a large scale deployment with many ProFTPd servers utilizing a separate
Clamd host over TCP for scalability and lower administrative overhead.
debian/changelog 0000644 0000000 0000000 00000001326 12213721245 011041 0 ustar proftpd-mod-clamav (0.10-1build2) saucy; urgency=low
* Rebuild for ProFTPd 1.3.5~rc3.
-- Colin Watson Tue, 10 Sep 2013 23:52:21 +0100
proftpd-mod-clamav (0.10-1build1) precise; urgency=low
* No change to rebuild agian current proftpd ABI
-- Mahyuddin Susanto Thu, 19 Jan 2012 18:19:01 +0700
proftpd-mod-clamav (0.10-1) unstable; urgency=low
[ Mahyuddin Susanto ]
* Initial release (Closes: #618431).
[ Francesco Paolo Lovergine ]
* Added a patch `cleanup' to avoid patching proftpd mod_core. Thanks TJ.
* Fixed debian/watch file to work.
* Do not install *.{la,a} files.
-- Francesco Paolo Lovergine Wed, 12 Oct 2011 16:29:18 +0200