From owner-freebsd-ports-bugs@FreeBSD.ORG Thu Aug 23 11:30:02 2007 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2BC6D16A418 for ; Thu, 23 Aug 2007 11:30:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 0697513C468 for ; Thu, 23 Aug 2007 11:30:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l7NBU1mM078570 for ; Thu, 23 Aug 2007 11:30:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l7NBU1sg078569; Thu, 23 Aug 2007 11:30:01 GMT (envelope-from gnats) Resent-Date: Thu, 23 Aug 2007 11:30:01 GMT Resent-Message-Id: <200708231130.l7NBU1sg078569@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Vladimir Korkodinov Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 921BA16A420 for ; Thu, 23 Aug 2007 11:20:23 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 7056B13C483 for ; Thu, 23 Aug 2007 11:20:23 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l7NBKMGk003099 for ; Thu, 23 Aug 2007 11:20:22 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.1/8.14.1/Submit) id l7NBKMgZ003098; Thu, 23 Aug 2007 11:20:22 GMT (envelope-from nobody) Message-Id: <200708231120.l7NBKMgZ003098@www.freebsd.org> Date: Thu, 23 Aug 2007 11:20:22 GMT From: Vladimir Korkodinov To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: ports/115752: [PATCH] By ftp /proftpd added support for clamav X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Aug 2007 11:30:02 -0000 >Number: 115752 >Category: ports >Synopsis: [PATCH] By ftp /proftpd added support for clamav >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Thu Aug 23 11:30:01 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Vladimir Korkodinov >Release: CURRENT >Organization: >Environment: FreeBSD xxxx 7.0-CURRENT FreeBSD 7.0-CURRENT #11: Thu Aug 23 14:52:33 YEKST 2007 viper@xxxx:/usr/obj/usr/src/sys/viper i386 >Description: Trying to add to the port support clamav. Used mod_clamav (http://www.uglyboxindustries.com/mod_clamav.html) with the minor revisions >How-To-Repeat: >Fix: Apply patch Patch attached with submission follows: diff -ruN proftpd.orig/Makefile proftpd/Makefile --- proftpd.orig/Makefile 2007-07-25 03:34:34.000000000 +0600 +++ proftpd/Makefile 2007-08-23 15:32:15.000000000 +0600 @@ -70,7 +70,8 @@ QUOTATAB_RADIUS "include mod_quotatab_radius" off \ BAN "include mod_ban (Requires CTRLS)" off \ NLS "Use nls (builds mod_lang)" off \ - CYRFIX "Use patch for fix cyrillic encoding" off + CYRFIX "Use patch for fix cyrillic encoding" off \ + CLAMAV "Use patch for support clamav " off MODULES?= LIBDIRS?= @@ -210,6 +211,14 @@ .endif .endif +.if defined(WITH_CLAMAV) +USE_CLAMAV= yes +MODULES:=${MODULES}:mod_clamav +LIB_DEPENDS+= clamav.2:${PORTSDIR}/security/clamav +INCLUDEDIRS:=${INCLUDEDIRS}:${LOCALBASE}/include +LIBDIRS:=${LIBDIRS}:${LOCALBASE}/lib +.endif + # mod_ifsession should be the last item in the modules list .if !defined(WITHOUT_IFSESSION) MODULES:=${MODULES}:mod_ifsession diff -ruN proftpd.orig/files/patch-contrib-mod_clamav.c proftpd/files/patch-contrib-mod_clamav.c --- proftpd.orig/files/patch-contrib-mod_clamav.c 1970-01-01 05:00:00.000000000 +0500 +++ proftpd/files/patch-contrib-mod_clamav.c 2007-08-23 17:01:53.000000000 +0600 @@ -0,0 +1,272 @@ +--- modules/mod_clamav.c.orig 2007-08-23 16:59:20.000000000 +0600 ++++ modules/mod_clamav.c 2007-08-23 17:01:21.000000000 +0600 +@@ -0,0 +1,269 @@ ++/* ++ * mod_clamav - ClamAV virus scanning module for ProFTPD ++ * Copyright (c) 2005-2006, Joseph Benden ++ * ++ * This program 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 program 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, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Furthermore, Joseph Benden gives permission to link this program with ++ * ClamAV, and distribute the resulting executable, without including the ++ * source code for ClamAV in the source distribution. ++ * ++ * ClamAV is available at http://www.clamav.net/ ++ * Non-official SuSE RPM packages for both ClamAV and ProFTPD are available ++ * at http://www.ispservices.com/ ++ * ++ * Thanks to TJ Saunders for his helpful comments and suggestions! ++ * ++ * DO NOT EDIT THE LINE BELOW ++ */ ++#include "conf.h" ++#include "privs.h" ++#include "clamav.h" ++ ++#define MOD_CLAMAV_VERSION "mod_clamav/0.5" ++module clamav_module; ++static int clamd_sockd = 0; ++int clamavd_session_start(int sockd); ++ ++/** ++ * Read the returned information from Clamavd. ++ */ ++int clamavd_result(int sockd, int warnClient, const char *filename) { ++ int infected = 0, waserror = 0, ret; ++ char buff[4096], *pt; ++ FILE *fd = 0; ++ ++ if((fd=fdopen(dup(sockd), "r")) == NULL) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Cant open descriptor for reading: %d", errno); ++ return -1; ++ } ++ ++ if(fgets(buff, sizeof(buff), fd)) { ++ if(strstr(buff, "FOUND\n")) { ++ ++infected; ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": warning: %s", buff); ++ /* Delete the upload */ ++ if(warnClient) ++ pr_response_add_err(R_DUP,"%s", buff); ++ pt = strrchr(buff, ':'); ++ *pt = 0; ++ if((ret=pr_fsio_unlink(filename))!=0) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": notice: unlink() failed: %d", errno); ++ } ++ } else if(strstr(buff, "ERROR\n")) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: %s", buff); ++ waserror = 1; ++ } ++ } ++ fclose(fd); ++ return infected ? infected : (waserror ? -1 : 0); ++} ++ ++/** ++ * Start a session with Clamavd. ++ */ ++int clamavd_session_start(int sockd) { ++ if(write(sockd, "SESSION\n", 8) <= 0) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Clamd didn't accept the session request."); ++ return -1; ++ } ++ return 0; ++} ++ ++/** ++ * End session. ++ */ ++int clamavd_session_stop(int sockd) { ++ if(write(sockd, "END\n", 4) <= 0) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Clamd didn't accept the session end request."); ++ return -1; ++ } ++ return 0; ++} ++ ++/** ++ * Request Clamavd to perform a scan. ++ */ ++int clamavd_scan(int sockd, const char *fullpath, int warnClient, const char *filename) { ++ char *scancmd = NULL; ++ ++ scancmd = calloc(strlen(fullpath) + 20, sizeof(char)); ++ sprintf(scancmd, "SCAN %s\n", fullpath); ++ ++ if(write(sockd, scancmd, strlen(scancmd)) <= 0) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Cant write to the ClamAVd socket: %d", errno); ++ free(scancmd); ++ return -1; ++ } ++ ++ free(scancmd); ++ return clamavd_result(sockd, warnClient, filename); ++} ++ ++/** ++ * Connect a socket to ClamAVd. ++ */ ++int clamavd_connect(char *clamhost) { ++ struct sockaddr_un server; ++ int sockd; ++ ++ PRIVS_ROOT; ++ memset((char*)&server, 0, sizeof(server)); ++ ++ /* Local Socket */ ++ server.sun_family = AF_UNIX; ++ strncpy(server.sun_path, clamhost, sizeof(server.sun_path)); ++ ++ if((sockd=socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { ++ PRIVS_RELINQUISH; ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Cannot create socket connection to ClamAVd: %d", errno); ++ return -1; ++ } ++ ++ if(connect(sockd, (struct sockaddr *)&server, sizeof(struct sockaddr_un)) < 0) { ++ close(sockd); ++ PRIVS_RELINQUISH; ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": error: Cannot connect to ClamAVd: (%d) %s", errno, clamhost); ++ return -1; ++ } ++ PRIVS_RELINQUISH; ++ ++ return sockd; ++} ++ ++MODRET clamav_scan(cmd_rec *cmd) { ++ config_rec *c = NULL; ++ int ret, infected = 0; ++ char fullpath[4096]; ++ ++ c = find_config(CURRENT_CONF, CONF_PARAM, "ClamAV", FALSE); ++ ++ if(!c || !*(int*)(c->argv[0])) ++ return DECLINED(cmd); ++ ++ /* hold on to the ClamWarn configuration option */ ++ c = find_config(CURRENT_CONF, CONF_PARAM, "ClamWarn", TRUE); ++ ++ /* Figure out the full path */ ++ if(session.chroot_path) { ++// sstrncpy(fullpath, strcmp(pr_fs_getvwd(), "/") ? ++// pdircat(cmd->tmp_pool, session.chroot_path, pr_fs_getvwd(), NULL) : ++// session.chroot_path, 4096); ++ sstrncpy(fullpath, session.chroot_path,(strlen(session.chroot_path)>4096) ? ++ 4096:4096-strlen (session.chroot_path)); ++ sstrcat(fullpath, "/", 4096 - strlen(fullpath)); ++ } else { ++// sstrncpy(fullpath, pr_fs_getcwd(), 4096); ++ sstrncpy(fullpath, "/", 1); ++ } ++ ++ sstrcat(fullpath, cmd->arg, 4096 - strlen(fullpath)); ++ ++ /* scan it! */ ++ if((ret=clamavd_scan(clamd_sockd, fullpath, (c ? *(int*)(c->argv[0]) : 0), cmd->arg)) >= 0) { ++ infected += ret; ++ } ++ ++ if(infected) { ++ return ERROR(cmd); ++ } ++ ++ if(c && *(int*)(c->argv[0])) ++ pr_response_add(R_226,"File passed ClamAV virus scanner."); ++ ++ return DECLINED(cmd); ++} ++ ++MODRET set_clamav(cmd_rec *cmd) { ++ int bool = -1; ++ config_rec *c = NULL; ++ ++ CHECK_ARGS(cmd, 1); ++ CHECK_CONF(cmd, CONF_ROOT|CONF_ANON|CONF_LIMIT|CONF_VIRTUAL|CONF_GLOBAL); ++ if((bool = get_boolean(cmd,1)) == -1) ++ CONF_ERROR(cmd, "requires a boolean value"); ++ ++ c = add_config_param(cmd->argv[0], 1, NULL); ++ c->argv[0] = pcalloc(c->pool, sizeof(int)); ++ *((int *) c->argv[0]) = bool; ++ c->flags |= CF_MERGEDOWN; ++ return HANDLED(cmd); ++} ++ ++MODRET set_clamavd_local_socket(cmd_rec *cmd) { ++ CHECK_ARGS(cmd, 1); ++ CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL); ++ ++ add_config_param_str("ClamLocalSocket", 1, cmd->argv[1]); ++ return HANDLED(cmd); ++} ++ ++static void clamav_shutdown(const void *event_data, void *user_data) { ++ pr_log_pri(PR_LOG_INFO, MOD_CLAMAV_VERSION ": info: disconnected from Clamd."); ++ if(clamd_sockd) { ++ clamavd_session_stop(clamd_sockd); ++ close(clamd_sockd); ++ } ++} ++ ++static int clamav_sess_init(void) { ++ char *local_socket = NULL; ++ ++ clamd_sockd = 0; ++ ++ local_socket = (char*)get_param_ptr(main_server->conf, "ClamLocalSocket", FALSE); ++ if(!local_socket) { ++ pr_log_pri(PR_LOG_INFO, MOD_CLAMAV_VERSION ": warning: No local socket was specified."); ++ return 0; ++ } ++ ++ if((clamd_sockd = clamavd_connect(local_socket)) < 0) { ++ pr_log_pri(PR_LOG_ERR, MOD_CLAMAV_VERSION ": Cannot connect to ClamAVd."); ++ return 0; ++ } ++ ++ clamavd_session_start(clamd_sockd); ++ ++ pr_event_register(&clamav_module, "core.exit", clamav_shutdown, NULL); ++ ++ return 0; ++} ++ ++static conftable clamav_conftab[] = { ++ { "ClamAV", set_clamav, NULL }, ++ { "ClamWarn", set_clamav, NULL }, ++ { "ClamLocalSocket", set_clamavd_local_socket, NULL }, ++ { NULL } ++}; ++ ++static cmdtable clamav_cmdtab[] = { ++ { POST_CMD, C_STOR, G_NONE, clamav_scan, TRUE, FALSE }, ++ { POST_CMD, C_STOU, G_NONE, clamav_scan, TRUE, FALSE }, ++ { POST_CMD, C_APPE, G_NONE, clamav_scan, TRUE, FALSE }, ++ { 0, NULL } ++}; ++ ++module clamav_module = { ++ NULL, ++ NULL, ++ 0x20, /* api ver */ ++ "clamav", ++ clamav_conftab, ++ clamav_cmdtab, ++ NULL, /* auth function table */ ++ NULL, /* init function */ ++ clamav_sess_init /* session init function */ ++}; ++ >Release-Note: >Audit-Trail: >Unformatted: