clamd/clamuko.c
e3aaff8e
 /*
81837459
  *  Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
e3aaff8e
  *
  *  This program is free software; you can redistribute it and/or modify
bb34cb31
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
e3aaff8e
  *
  *  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
48b7b4a7
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
e3aaff8e
  */
 
6d6e8271
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
e3aaff8e
 #ifdef CLAMUKO
 
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <signal.h>
 #include <pthread.h>
bd8603aa
 
 #include "libclamav/clamav.h"
 
 #include "shared/cfgparser.h"
 #include "shared/output.h"
e3aaff8e
 
 #include "server.h"
 #include "others.h"
 #include "dazukoio.h"
 #include "clamuko.h"
 
32fc1d7b
 struct dazuko_access *acc;
e3aaff8e
 
fc83da82
 static void clamuko_exit(int sig)
e3aaff8e
 {
 
     logg("*Clamuko: clamuko_exit(), signal %d\n", sig);
 
     if(clamuko_scanning) {
32fc1d7b
 	logg("*Clamuko: stopped while scanning %s\n", acc->filename);
 	acc->deny = 0;
e3aaff8e
 	dazukoReturnAccess(&acc); /* is it needed ? */
     }
 
32fc1d7b
     if(dazukoUnregister())
 	logg("!Can't unregister with Dazuko\n");
 
46c2e927
     logg("Clamuko stopped.\n");
2b278a02
 
     pthread_exit(NULL);
e3aaff8e
 }
 
 void *clamukoth(void *arg)
 {
 	struct thrarg *tharg = (struct thrarg *) arg;
 	sigset_t sigset;
fb787a06
 	const char *virname;
e3aaff8e
         struct sigaction act;
 	unsigned long mask = 0;
 	const struct cfgstruct *pt;
 	short int scan;
8d5e0ac0
 	int sizelimit = 0;
e3aaff8e
 	struct stat sb;
 
 
46c2e927
     clamuko_scanning = 0;
e3aaff8e
 
     /* ignore all signals except SIGUSR1 */
     sigfillset(&sigset);
     sigdelset(&sigset, SIGUSR1);
ac480646
     sigdelset(&sigset, SIGSEGV);
e3aaff8e
     pthread_sigmask(SIG_SETMASK, &sigset, NULL);
     act.sa_handler = clamuko_exit;
     sigfillset(&(act.sa_mask));
     sigaction(SIGUSR1, &act, NULL);
ac480646
     sigaction(SIGSEGV, &act, NULL);
e3aaff8e
 
     /* register */
32fc1d7b
     if(dazukoRegister("ClamAV", "r+")) {
e3aaff8e
 	logg("!Clamuko: Can't register with Dazuko\n");
 	return NULL;
     } else
 	logg("Clamuko: Correctly registered with Dazuko.\n");
 
     /* access mask */
81837459
     if(cfgopt(tharg->copt, "ClamukoScanOnOpen")->enabled) {
e3aaff8e
 	logg("Clamuko: Scan-on-open mode activated.\n");
32fc1d7b
 	mask |= DAZUKO_ON_OPEN;
e3aaff8e
     }
81837459
     if(cfgopt(tharg->copt, "ClamukoScanOnClose")->enabled) {
e3aaff8e
 	logg("Clamuko: Scan-on-close mode activated.\n");
32fc1d7b
 	mask |= DAZUKO_ON_CLOSE;
e3aaff8e
     }
81837459
     if(cfgopt(tharg->copt, "ClamukoScanOnExec")->enabled) {
e3aaff8e
 	logg("Clamuko: Scan-on-exec mode activated.\n");
32fc1d7b
 	mask |= DAZUKO_ON_EXEC;
e3aaff8e
     }
 
     if(!mask) {
 	logg("!Access mask is not configured properly.\n");
35c49455
 	dazukoUnregister();
e3aaff8e
 	return NULL;
     }
 
     if(dazukoSetAccessMask(mask)) {
 	logg("!Clamuko: Can't set access mask in Dazuko.\n");
35c49455
 	dazukoUnregister();
e3aaff8e
 	return NULL;
     }
 
81837459
     if((pt = cfgopt(tharg->copt, "ClamukoIncludePath"))->enabled) {
e3aaff8e
 	while(pt) {
 	    if((dazukoAddIncludePath(pt->strarg))) {
 		logg("!Clamuko: Dazuko -> Can't include path %s\n", pt->strarg);
35c49455
 		dazukoUnregister();
e3aaff8e
 		return NULL;
 	    } else
 		logg("Clamuko: Included path %s\n", pt->strarg);
 
 	    pt = (struct cfgstruct *) pt->nextarg;
 	}
     } else {
 	logg("!Clamuko: please include at least one path.\n");
35c49455
 	dazukoUnregister();
e3aaff8e
 	return NULL;
     }
 
81837459
     if((pt = cfgopt(tharg->copt, "ClamukoExcludePath"))->enabled) {
e3aaff8e
 	while(pt) {
 	    if((dazukoAddExcludePath(pt->strarg))) {
 		logg("!Clamuko: Dazuko -> Can't exclude path %s\n", pt->strarg);
35c49455
 		dazukoUnregister();
e3aaff8e
 		return NULL;
 	    } else
 		logg("Clamuko: Excluded path %s\n", pt->strarg);
 
 	    pt = (struct cfgstruct *) pt->nextarg;
 	}
     }
 
81837459
     sizelimit = cfgopt(tharg->copt, "ClamukoMaxFileSize")->numarg;
e3aaff8e
     if(sizelimit)
 	logg("Clamuko: Max file size limited to %d bytes.\n", sizelimit);
     else
 	logg("Clamuko: File size limit disabled.\n");
 
     while(1) {
 
 	if(dazukoGetAccess(&acc) == 0) {
 	    clamuko_scanning = 1;
 	    scan = 1;
 
 	    if(sizelimit) {
32fc1d7b
 		stat(acc->filename, &sb);
e3aaff8e
 		if(sb.st_size > sizelimit) {
 		    scan = 0;
32fc1d7b
 		    logg("*Clamuko: %s skipped (too big)\n", acc->filename);
e3aaff8e
 		}
 	    }
 
a57e3d41
 	    if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->engine, tharg->limits, tharg->options) == CL_VIRUS) {
32fc1d7b
 		logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
557b40cc
 		virusaction(acc->filename, virname, tharg->copt);
32fc1d7b
 		acc->deny = 1;
e3aaff8e
 	    } else
32fc1d7b
 		acc->deny = 0;
e3aaff8e
 
 	    if(dazukoReturnAccess(&acc)) {
 		logg("!Can't return access to Dazuko.\n");
 		logg("Clamuko stopped.\n");
 		dazukoUnregister();
 		clamuko_scanning = 0;
 		return NULL;
 	    }
 
 	    clamuko_scanning = 0;
 	}
     }
 
     /* can't be ;) */
     return NULL;
 }
 
 #endif