示例#1
0
int clamav_scanfile(void *state, const char *fname,
		    const char **virname)
{
    struct clamav_state *st = (struct clamav_state *) state;
    int r;

    /* scan file */
    r = cl_scanfile(fname, virname, NULL, st->av_engine,
		    CL_SCAN_STDOPT);

    switch (r) {
    case CL_CLEAN:
	/* do nothing */
	break;
    case CL_VIRUS:
	return 1;
	break;

    default:
	printf("cl_scanfile error: %s\n", cl_strerror(r));
	syslog(LOG_ERR, "cl_scanfile error: %s\n", cl_strerror(r));
	break;
    }

    return 0;
}
示例#2
0
END_TEST

START_TEST (test_cl_scanfile_allscan)
{
    const char *virname = NULL;
    const char **virpp = &virname;
    char file[256];
    unsigned long size;
    unsigned long int scanned = 0;
    int ret;

    int fd = get_test_file(_i, file, sizeof(file), &size);
    close(fd);

    cli_dbgmsg("scanning (scanfile_allscan) %s\n", file);
    ret = cl_scanfile(file, virpp, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT);
    cli_dbgmsg("scan end (scanfile_allscan) %s\n", file);

    if (!FALSE_NEGATIVE) {
        fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_allscan failed for %s: %s", file, cl_strerror(ret));
        virpp = (const char **)*virpp; /* allscan api hack */
        fail_unless_fmt(*virpp && !strcmp(*virpp, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", *virpp);
        free((void *)virpp);
    }
}
/* Scans a file with clam AV
 *
 */
int scan(char *inputFile, struct cl_engine* engine) {
  // perform the scan. if you need to scan multiple files, you do not need to
  // re-initialize/compile the scan engine. just keep calling cl_scanfile(), 
  // once for each new file you want to scan. the function should be
  // thread safe.
  const char* virus_name;
  int scan_result;
  long unsigned int scanned;  // unimportant. its use in cl_scanfile can be
                              // replaced with NULL. see manual for
                              // documentation.

  scan_result = cl_scanfile(inputFile, &virus_name, &scanned, engine,
    CL_SCAN_STDOPT);
  switch (scan_result) {
    case CL_VIRUS:
      printf("[X] found virus: [%s]\n", virus_name);
      return 1;
    case CL_CLEAN:
      printf("[O] clean.\n");
      break;
    default:  // should not get here
      break;
  }
  // all done
  return 0;
}
示例#4
0
 /**
  *      Scan email for virus. Returns 1 if virus
  *      detected or 0 if no virus is detected. Sets
  *      lscan.virname to virua or error output...
  */
 int scan_clamav(char * scanpath) {

         sprintf(lscan.scanpath, "%s", scanpath);
         lscan.iNo = 0;

         /** lets load all our virus defs database's into memory */
         lscan.root = NULL;      /** without this line, the dbload will crash... */
         if((lscan.i = cl_loaddbdir(cl_retdbdir(), &lscan.root, &lscan.iNo))) {
                 sprintf(lscan.virname, "error: [%s]", cl_perror(lscan.i));
         } else {
                 if((lscan.i = cl_build(lscan.root))) {
                         sprintf(lscan.virname, "database initialization error: [%s]", cl_perror(lscan.i));
                         cl_free(lscan.root);
                 }
                 memset(&lscan.limits, 0x0, sizeof(struct cl_limits));
                 lscan.limits.maxfiles = 1000;                   /** max files */
                 lscan.limits.maxfilesize = 10 * 1048576;        /** maximal archived file size == 10 Mb */
                 lscan.limits.maxreclevel = 12;                  /** maximal recursion level */
                 lscan.limits.maxratio = 200;                    /** maximal compression ratio */
                 lscan.limits.archivememlim = 0;                 /** disable memory limit for bzip2 scanner */

                 if ((lscan.i = cl_scanfile(lscan.scanpath, (const char **)&lscan.virname, NULL, lscan.root,
                 &lscan.limits, CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_OLE2 | CL_SCAN_BLOCKBROKEN | CL_SCAN_HTML | CL_SCAN_PE)) != CL_VIRUS) {
                         if (lscan.i != CL_CLEAN) {
                                 sprintf(lscan.virname, "error: [%s]", cl_perror(lscan.i));
                         } else {
                                 lscan.virname = NULL;
                         }
                 }
                 if (lscan.root != NULL) {
                         cl_free(lscan.root);
                 }
                 memset(&lscan.limits, 0x0, sizeof(struct cl_limits));
         }

         /** lets delete the spool message as we don't need it any more */
         if (lscan.virname != NULL) {            /** remove the file if we have a virus as we are going to reject it */
                 return(1);
         } else {                                /** else keep the file for spam filtering */
                 return(0);
         }

         return(1);

 } /** scan_clamav */
END_TEST

//* int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) */
START_TEST (test_cl_scanfile)
{
    const char *virname = NULL;
    char file[256];
    unsigned long size;
    unsigned long int scanned = 0;
    int ret;

    int fd = get_test_file(_i, file, sizeof(file), &size);
    close(fd);

    cli_dbgmsg("scanning (scanfile) %s\n", file);
    ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
    cli_dbgmsg("scan end (scanfile) %s\n", file);

    if (!FALSE_NEGATIVE) {
      fail_unless_fmt(ret == CL_VIRUS , "cl_scanfile failed for %s: %s", file, cl_strerror(ret));
      fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
    }
}
示例#6
0
文件: clamuko.c 项目: OPSF/uClinux
void *clamukoth(void *arg)
{
	struct thrarg *tharg = (struct thrarg *) arg;
	sigset_t sigset;
	const char *virname;
        struct sigaction act;
	unsigned long mask = 0;
	const struct optstruct *pt;
	short int scan;
	int sizelimit = 0;
	struct stat sb;


    clamuko_scanning = 0;

    /* ignore all signals except SIGUSR1 */
    sigfillset(&sigset);
    sigdelset(&sigset, SIGUSR1);
    /* The behavior of a process is undefined after it ignores a 
     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
    sigdelset(&sigset, SIGFPE);
    sigdelset(&sigset, SIGILL);
    sigdelset(&sigset, SIGSEGV);
#ifdef SIGBUS    
    sigdelset(&sigset, SIGBUS);
#endif
    pthread_sigmask(SIG_SETMASK, &sigset, NULL);
    act.sa_handler = clamuko_exit;
    sigfillset(&(act.sa_mask));
    sigaction(SIGUSR1, &act, NULL);
    sigaction(SIGSEGV, &act, NULL);

    /* register */
    if(dazukoRegister("ClamAV", "r+")) {
	logg("!Clamuko: Can't register with Dazuko\n");
	return NULL;
    } else
	logg("Clamuko: Correctly registered with Dazuko.\n");

    /* access mask */
    if(optget(tharg->opts, "ClamukoScanOnOpen")->enabled) {
	logg("Clamuko: Scan-on-open mode activated.\n");
	mask |= DAZUKO_ON_OPEN;
    }
    if(optget(tharg->opts, "ClamukoScanOnClose")->enabled) {
	logg("Clamuko: Scan-on-close mode activated.\n");
	mask |= DAZUKO_ON_CLOSE;
    }
    if(optget(tharg->opts, "ClamukoScanOnExec")->enabled) {
	logg("Clamuko: Scan-on-exec mode activated.\n");
	mask |= DAZUKO_ON_EXEC;
    }

    if(!mask) {
	logg("!Access mask is not configured properly.\n");
	dazukoUnregister();
	return NULL;
    }

    if(dazukoSetAccessMask(mask)) {
	logg("!Clamuko: Can't set access mask in Dazuko.\n");
	dazukoUnregister();
	return NULL;
    }

    if((pt = optget(tharg->opts, "ClamukoIncludePath"))->enabled) {
	while(pt) {
	    if((dazukoAddIncludePath(pt->strarg))) {
		logg("!Clamuko: Dazuko -> Can't include path %s\n", pt->strarg);
		dazukoUnregister();
		return NULL;
	    } else
		logg("Clamuko: Included path %s\n", pt->strarg);

	    pt = (struct optstruct *) pt->nextarg;
	}
    } else {
	logg("!Clamuko: please include at least one path.\n");
	dazukoUnregister();
	return NULL;
    }

    if((pt = optget(tharg->opts, "ClamukoExcludePath"))->enabled) {
	while(pt) {
	    if((dazukoAddExcludePath(pt->strarg))) {
		logg("!Clamuko: Dazuko -> Can't exclude path %s\n", pt->strarg);
		dazukoUnregister();
		return NULL;
	    } else
		logg("Clamuko: Excluded path %s\n", pt->strarg);

	    pt = (struct optstruct *) pt->nextarg;
	}
    }

    sizelimit = optget(tharg->opts, "ClamukoMaxFileSize")->numarg;
    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) {
		stat(acc->filename, &sb);
		if(sb.st_size > sizelimit) {
		    scan = 0;
		    logg("*Clamuko: %s skipped (too big)\n", acc->filename);
		}
	    }

	    if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->engine, tharg->options) == CL_VIRUS) {
		logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
		virusaction(acc->filename, virname, tharg->opts);
		acc->deny = 1;
	    } else
		acc->deny = 0;

	    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;
}
示例#7
0
static int scanstdin(const struct cl_engine *engine, const struct optstruct *opts, int options)
{
	int ret;
	unsigned int fsize = 0;
	const char *virname, *tmpdir;
	char *file, buff[FILEBUFF];
	size_t bread;
	FILE *fs;

    if(optget(opts, "tempdir")->enabled) {
	tmpdir = optget(opts, "tempdir")->strarg;
    } else
	/* check write access */
	tmpdir = cli_gettmpdir();

    if(checkaccess(tmpdir, CLAMAVUSER, W_OK) != 1) {
	logg("!Can't write to temporary directory\n");
	return 2;
    }

    if(!(file = cli_gentemp(tmpdir))) {
	logg("!Can't generate tempfile name\n");
	return 2;
    }

    if(!(fs = fopen(file, "wb"))) {
	logg("!Can't open %s for writing\n", file);
	free(file);
	return 2;
    }

    while((bread = fread(buff, 1, FILEBUFF, stdin))) {
	fsize += bread;
	if(fwrite(buff, 1, bread, fs) < bread) {
	    logg("!Can't write to %s\n", file);
	    free(file);
	    fclose(fs);
	    return 2;
	}
    }
    fclose(fs);

    logg("*Checking %s\n", file);
    info.files++;
    info.rblocks += fsize / CL_COUNT_PRECISION;

    if((ret = cl_scanfile(file, &virname, &info.blocks, engine, options)) == CL_VIRUS) {
	logg("stdin: %s FOUND\n", virname);
	info.ifiles++;

	if(bell)
	    fprintf(stderr, "\007");

    } else if(ret == CL_CLEAN) {
	if(!printinfected)
	    mprintf("stdin: OK\n");
    } else {
	if(!printinfected)
	    logg("stdin: %s ERROR\n", cl_strerror(ret));
	info.errors++;
    }

    unlink(file);
    free(file);
    return ret;
}